Запросы по нескольким типам эластичного поиска - PullRequest
4 голосов
/ 27 января 2020

Я хочу получить документы, представленные в нескольких типах (тип1 И тип2 И тип3 ...) в Elasti c Поиск 5.0. Я знаю, что поиск по нескольким типам возможен с использованием нескольких типов, таких как type1, type2 в URL, а также путем фильтрации поля _type. Но все эти условия - ИЛИ (тип1 ИЛИ тип2). Как мне выполнить условие AND?

Вот два документа в моем ES,

{
   "_index":"cust_58e8700034fa4e368590fb1396e2641c",
   "_type":"unique-fp-domains",
   "_id":"n_d4dbba7309a94503b25eca735078f17c_258b3ad1a11aba282f35908662bdc5432d68fd96bf3ca90013dcdd5764331399",
   "_version":2,
   "_score":1,
   "_source":{
      "mg_timestamp":1579866709096,
      "violated-directive":"connect-src",
      "fp-hash":"258b3ad1a11aba282f35908662bdc5432d68fd96bf3ca90013dcdd5764331399",
      "time":1579866709096,
      "scan-id":"n_d4dbba7309a94503b25eca735078f17c",
      "blocked-uri":"play.sundaysky.com"
   }
}


{
   "_index":"cust_58e8700034fa4e368590fb1396e2641c",
   "_type":"tag-alexa-top1k-using-csp-tld-domain",
   "_id":"AW_XY4P4kmprPQ28bTUb",
   "_version":1,
   "_score":1,
   "_source":{
      "tagged-domain":"sundaysky.com",
      "tag-guidance":"FP",
      "additional-tag-metadata-isbase64-encoded":"eyJ0b3RhbC1hbGV4YS1tYXRjaGVzIjoyMzh9",
      "project-id":2,
      "fp-hash":"258b3ad1a11aba282f35908662bdc5432d68fd96bf3ca90013dcdd5764331399",
      "scan-id":"n_d4dbba7309a94503b25eca735078f17c",
   }
}

Я хочу получить документы из одного индекса из указанных 2 типов с помощью "scan-id":"n_d4dbba7309a94503b25eca735078f17c"

Я пробовал это,

{
  "size": 100,
  "query": {
    "bool": {
      "must": [
        {
          "bool": {
            "filter": [
              {
                "term": {
                  "_type": {
                    "value": "tag-alexa-top1k-using-csp-tld-domain"
                  }
                }
              },
              {
                "term": {
                  "scan-id": {
                    "value": "n_d4dbba7309a94503b25eca735078f17c"
                  }
                }
              }
            ]
          }
        },
        {
          "bool": {
            "filter": [
              {
                "term": {
                  "_type": {
                    "value": "unique-fp-domains"
                  }
                }
              },
              {
                "term": {
                  "scan-id": {
                    "value": "n_d4dbba7309a94503b25eca735078f17c"
                  }
                }
              }
            ]
          }
        }
      ]
    }
  }
}

Но это не работает.

Ответы [ 4 ]

1 голос
/ 29 января 2020

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 не очень хорош для управления отношениями между объектами, но есть несколько способов справиться с ними .

Надеюсь, это поможет!

1 голос
/ 28 января 2020

Я думаю, что этот запрос выяснит вашу проблему;

"query": {
  "bool": {
    "must": [
      {
        "terms": {
          "_type": "tag-alexa-top1k-using-csp-tld-domain"
        }
      },
      {
        "terms": {
          "_type": "unique-fp-domains"
        }
      }
    ],
    "filter": [
      {
        "scan-id": {
          "_type": "n_d4dbba7309a94503b25eca735078f17c"
        }
      }
    ]
  }
}
0 голосов
/ 28 января 2020

"query": {"query_string": {"query": "(_type: unique-fp-domains ИЛИ tag-alexa-top1k-using-csp-tld-domain) И (идентификатор_сканирования: n_d4dbba7309a94503b25eca735078f17 c)
}}

0 голосов
/ 28 января 2020

вы можете использовать msearch. Это может объединить несколько поисков. Вы можете найти больше информации об этом в их документации. https://www.elastic.co/guide/en/elasticsearch/reference/current/search-multi-search.html

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...