Elasticsearch не подходит для объединения различных коллекций документов, но в вашем случае вы можете решить проблему с помощью отношения parent-child
.
Как запрашивать многие типы индексов вместе в стиле AND?
В случае, если у вас есть отношение один ко многим , вы можете смоделировать его с помощью parent-child
, Предположим, что тип unique-fp-domains
является «родительским» типом, а поле scan-id
является уникальным идентификатором. Предположим также, что tag-alexa-top1k-using-csp-tld-domain
является «дочерним элементом», и каждый документ типа tag-alexa-top1k-using-csp-tld-domain
ссылается ровно на 1 документ в unique-fp-domains
.
Затем мы должны создать отображение Elasticsearch следующим образом:
PUT /cust_58
{
"mappings": {
"unique-fp-domains": {},
"tag-alexa-top1k-using-csp-tld-domain": {
"_parent": {
"type": "unique-fp-domains"
}
}
}
}
И вставьте документы следующим образом:
# "parent"
PUT /cust_58/unique-fp-domains/n_d4dbba7309a94503b25eca735078f17c
{
"mg_timestamp": 1579866709096,
"violated-directive": "connect-src",
"fp-hash": "258b3ad1a11aba282f35908662bdc5432d68fd96bf3ca90013dcdd5764331399",
"time": 1579866709096,
"scan-id": "n_d4dbba7309a94503b25eca735078f17c",
"blocked-uri": "play.sundaysky.com"
}
# "child"
POST /cust_58/tag-alexa-top1k-using-csp-tld-domain?parent=n_d4dbba7309a94503b25eca735078f17c
{
"tagged-domain": "sundaysky.com",
"tag-guidance": "FP",
"additional-tag-metadata-isbase64-encoded": "eyJ0b3RhbC1hbGV4YS1tYXRjaGVzIjoyMzh9",
"project-id": 2,
"fp-hash": "258b3ad1a11aba282f35908662bdc5432d68fd96bf3ca90013dcdd5764331399",
"scan-id": "n_d4dbba7309a94503b25eca735078f17c"
}
Теперь мы сможем запрашивать родительские объекты, у которых есть любой дочерний объект, связанный с ним == присоединиться к родительскому идентификатору. быть scan-id
, предоставив _id
документа вручную.
Запрос будет использовать has_child
и будет выглядеть так:
POST /cust_58/unique-fp-domains/_search
{
"query": {
"has_child": {
"type": "tag-alexa-top1k-using-csp-tld-domain",
"query": {
"match_all": {}
},
"inner_hits": {}
}
}
}
Обратите внимание, что мы используем inner_hits
, чтобы Elasticsearch извлекал совпадающие «дочерние» документы.
Вывод будет выглядеть следующим образом:
"hits": [
{
"_index": "cust_58",
"_type": "unique-fp-domains",
"_id": "n_d4dbba7309a94503b25eca735078f17c",
"_score": 1.0,
"_source": {
"mg_timestamp": 1579866709096,
"violated-directive": "connect-src",
...
},
"inner_hits": {
"tag-alexa-top1k-using-csp-tld-domain": {
"hits": {
"total": 1,
"max_score": 1.0,
"hits": [
{
"_type": "tag-alexa-top1k-using-csp-tld-domain",
"_id": "AW_xhfnnIzWDkoWd1czA",
"_score": 1.0,
"_routing": "n_d4dbba7309a94503b25eca735078f17c",
"_parent": "n_d4dbba7309a94503b25eca735078f17c",
"_source": {
"tagged-domain": "sundaysky.com",
...
}
Каковы недостатки использования parent-child
?
- родительский идентификатор должен быть уникальным
- объединение только по родительскому идентификатору
- некоторые накладные расходы производительности :
Если вы заботитесь о производительности запросов, вам не следует использовать этот запрос.
- , чтобы включить родитель-потомок, нужно будет изменить сопоставления и переиндексировать существующие данные
Другие важные вещи, которые следует учитывать
В Elasticsearch 6, типы были удалены . Хорошей новостью является то, что уже начиная с Elasticsearch 5 можно использовать join
тип данных .
В общем, Elasticsearch не очень хорош для управления отношениями между объектами, но есть несколько способов справиться с ними .
Надеюсь, это поможет!