Elasticsearch отдельная агрегация на основе значений из первого - PullRequest
0 голосов
/ 29 апреля 2020

Я использую Elasticsearch 6.8.8 и пытаюсь агрегировать количество сущностей и отношений за определенный период времени.

Вот структура данных и примеры значений индекса:

date           entityOrRelationshipId startId endId     type 
=========================================================================
DATETIMESTAMP  ENT1_ID                null     null      ENTITY
DATETIMESTAMP  ENT2_ID                null     null      ENTITY
DATETIMESTAMP  ENT3_ID                null     null      ENTITY
DATETIMESTAMP  REL1_ID                ENT1_ID  ENT2_ID   RELATIONSHIP
DATETIMESTAMP  REL2_ID                ENT3_ID  ENT1_ID   RELATIONSHIP
etc.

Для данного идентификатора объекта я хочу получить 50 лучших отношений. Я начал со следующего запроса.

{
    "size": 0,
    "query": {
        "bool": {
            "must": [
                {
                    "range": {
                        "date": {
                            "gte": "2020-04-01T00:00:00.000+00:00",
                            "lt": "2020-04-28T00:00:00.000+00:00"
                        }
                    }
                }
            ]
        }
    },
    "aggs": {
        "my_rels": {
            "filter": {
                "bool": {
                    "must": [
                        {
                            "term": {
                                "type": "RELATIONSHIP"
                            }
                        },
                        {
                            "bool": {
                                "should": [
                                    {
                                        "term": {"startId": "ENT1_ID"}
                                    },
                                    {
                                        "term": {"endId": "ENT1_ID"}
                                    }
                                ]
                            }
                        }
                    ]
                }
            },
            "aggs": {
                "my_rels2": {
                    "terms": {
                        "field": "entityOrRelationshipId",
                        "size": 50
                    },
                    "aggs": {
                        "my_rels3": {
                            "top_hits": {
                                "_source": {
                                    "includes": ["startId","endId"]
                                },
                                "size": 1
                            }
                        }
                    }
                }
            }
        }
    }
}

Это приводит к следующим результатам:

{
    "took": 54,
    "timed_out": false,
    "_shards": {
        "total": 5,
        "successful": 5,
        "skipped": 0,
        "failed": 0
    },
    "hits": {
        "total": 93122,
        "max_score": 0.0,
        "hits": []
    },
    "aggregations": {
        "my_rels": {
            "doc_count": 332,
            "my_rels2": {
                "doc_count_error_upper_bound": 6,
                "sum_other_doc_count": 259,
                "buckets": [
                    {
                        "key": "REL1_ID",
                        "doc_count": 47,
                        "my_rels3": {
                            "hits": {
                                "total": 47,
                                "max_score": 1.0,
                                "hits": [
                                    {
                                        "_index": "trends",
                                        "_type": "trend",
                                        "_score": 1.0,
                                        "_source": {
                                            "endId": "ENT2_ID",
                                            "startId": "ENT1_ID"
                                        }
                                    }
                                ]
                            }
                        }
                    },
                    {
                        "key": "REL2_ID",
                        "doc_count": 26,
                        "my_rels3": {
                            "hits": {
                                "total": 26,
                                "max_score": 1.0,
                                "hits": [
                                    {
                                        "_index": "trends",
                                        "_type": "trend",
                                        "_score": 1.0,
                                        "_source": {
                                            "endId": "ENT1_ID",
                                            "startId": "ENT3_ID"
                                        }
                                    }
                                ]
                            }
                        }
                    }
                ]
            }
        }
    }
}

Здесь перечислены 50 лучших отношений. Для каждого отношения перечисляются идентификатор отношения, количество и идентификаторы объекта (startId, endId). То, что я хотел бы сделать сейчас, - это произвести другую агрегацию подсчетов объектов для этих отдельных объектов. В идеале это должна быть не вложенная агрегация, а отдельная, использующая релевантности, определенные в первой агрегации.

Возможно ли это сделать в этом запросе?

1 Ответ

0 голосов
/ 30 апреля 2020

К сожалению, вы не можете агрегировать результаты top_hits в Elasticsearch. Вот ссылка на проблему GitHub .

У вас может быть другая агрегация на параллельном уровне top_hit, но у вас не может быть никакой дополнительной агрегации ниже top_hit.

У вас может быть агрегация параллельных уровней, например:

"aggs": {
    "top_hits_agg": {
        "top_hits": {
            "size": 10,
            "_source": {
              "includes": ["score"]
            }
        }
    },
    "avg_agg": {
        "avg": {
            "field": "score"
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...