Как на самом деле означает предложение must с массивом предложений соответствия?

У меня есть elasticsearch query, который выглядит так ...

  "query": {
    "bool": {
      "must": [{
        "match": {"attrs.name": "username"}
      }, {
        "match": {"attrs.value": "johndoe"}
      }]
    }
  }

... и документы в индексе, которые выглядят следующим образом:

{
  "key": "value",
  "attrs": [{
    "name": "username",
    "value": "jimihendrix"
  }, {
    "name": "age",
    "value": 23
  }, {
    "name": "alias",
    "value": "johndoe"
  }]
}

Что из следующего действительно означает этот запрос?

  1. Документ должен содержать attrs.name = username ИЛИ attrs.value = johndoe
  2. Или документ должен содержать оба, attrs.name = username И attrs.value = johndoe, даже если они могут соответствовать различным элементам в массиве attrs (это будет означать, что документ, указанный выше, будет соответствовать запросу )
  3. Или документ должен содержать оба attrs.name = username И attrs.value = johndoe, но они должны соответствовать одному и тому же элементу в массиве attrs (что будет означать, что документ, указанный выше, не будет соответствовать запрос)

Кроме того, как мне написать запрос для выражения №3 из приведенного выше списка, т. е. документ должен соответствовать, только если единственный элемент внутри массива attrs совпадает с обоими следующие условия:

  • attrs.name = имя пользователя
  • attrs.value = johndoe

person Saurabh Nanda    schedule 28.05.2020    source источник
comment
можешь поделиться своим картированием?   -  person user156327    schedule 28.05.2020
comment
@OpsterElasticsearchNinja Я новичок в ES, поэтому я не могу понять базовую терминологию. Что такое картографирование?   -  person Saurabh Nanda    schedule 28.05.2020
comment
@SaurabhNanda, я попробовал это на ваших образцах данных и, используя тип данных nested, получил ожидаемый результат, обратитесь к моему ответу. Сопоставление означает, как вы моделируете свои данные в Elasticsearch, т.е. какой тип полей использовать, какой анализатор использовать, вы можете думать об этом как о табличном определении SQL, см. elastic.co/guide/en/elasticsearch/reference/current/ для получения дополнительных сведений.   -  person    schedule 28.05.2020
comment
@SaurabhNanda, у вас была возможность ознакомиться с моим ответом, дайте мне знать, если вам понадобится дополнительная информация.   -  person    schedule 01.06.2020


Ответы (2)


Должен означает "И", поэтому возвращается документ, удовлетворяющий всем условиям в запросе на сопоставление.

Должен не соответствовать пункту 1. Документ должен содержать либо attrs.name = username ИЛИ attrs.value = johndoe - вам нужно предложение should, которое работает как «ИЛИ»

Будет ли Must удовлетворять пункту 2 или пункту 3, зависит от типа поля "attrs".

Если тип поля "attr" - объект, тогда поля сглаживаются, поэтому между разными полями массива не поддерживается связь. Таким образом, запрос должен вернуть документ, если какие-либо attrs.name = "username" и attrs.value = "John doe", даже если они не являются частью одного и того же объекта в этом массиве.

Если вы хотите, чтобы объект в массиве действовал как отдельный документ, вам нужно использовать вложенное поле и используйте вложенный запрос для поиска документов

{
  "query": {
    "nested": {
      "path": "attrs",
      "inner_hits": {}, --> returns matched nested documents
      "query": {
        "bool": {
          "must": [
            {
              "match": {
                "attrs.name": "username"
              }
            },
            {
              "match": {
                "attrs.value": "johndoe"
              }
            }
          ]
        }
      }
    }
  }
}

совпадения в ответе будут содержать все вложенные документы, чтобы получить все совпавшие вложенные документы, необходимо указать inner_hits

person jaspreet chahal    schedule 28.05.2020

Исходя из ваших требований, вам необходимо определить свое поле attrs как вложенное, см. вложенный тип в Elasticsearch для получения дополнительной информации. Отказ от ответственности: отношения поддерживаются, но запрос требует больших затрат.

Ответ на два других вопроса также зависит от того, какой тип данных вы используете, см. тип данных вложенный или объектный для получения более подробной информации.

Изменить: решение с использованием образца сопоставления, примеров документов и ожидаемого результата

Отображение индекса с использованием вложенного типа

{
    "mappings": {
        "properties": {
            "attrs": {
                "type": "nested"
            }
        }
    }
}

Индексируйте 2 образец документа, один из которых разделяет критерии, а другой - нет.

{
    "attrs": [
        {
            "name": "username",
            "value": "johndoe"
        },
        {
            "name": "alias",
            "value": "myname"
        }
    ]
}

Другой, который служит критериям

{
    "attrs": [
        {
            "name": "username",
            "value": "jimihendrix"
        },
        {
            "name": "age",
            "value": 23
        },
        {
            "name": "alias",
            "value": "johndoe"
        }
    ]
}

И поисковый запрос

{
  "query": {
    "nested": {
      "path": "attrs",
      "inner_hits": {}, 
      "query": {
        "bool": {
          "must": [
            {
              "match": {
                "attrs.name": "username"
              }
            },
            {
              "match": {
                "attrs.value": "johndoe"
              }
            }
          ]
        }
      }
    }
  }
}

И результат поиска

 "hits": [
            {
                "_index": "nested",
                "_type": "_doc",
                "_id": "2",
                "_score": 1.7509375,
                "_source": {
                    "attrs": [
                        {
                            "name": "username",
                            "value": "johndoe"
                        },
                        {
                            "name": "alias",
                            "value": "myname"
                        }
                    ]
                },
                "inner_hits": {
                    "attrs": {
                        "hits": {
                            "total": {
                                "value": 1,
                                "relation": "eq"
                            },
                            "max_score": 1.7509375,
                            "hits": [
                                {
                                    "_index": "nested",
                                    "_type": "_doc",
                                    "_id": "2",
                                    "_nested": {
                                        "field": "attrs",
                                        "offset": 0
                                    },
                                    "_score": 1.7509375,
                                    "_source": {
                                        "name": "username",
                                        "value": "johndoe"
                                    }
                                }
                            ]
                        }
                    }
                }
            }
        ]
person Community    schedule 28.05.2020