#elasticsearch #match #term
#elasticsearch #совпадение
Вопрос:
У меня проблема с ES, когда я пытаюсь проверить наличие 2 (или 2) значений; которые существуют во вложенном документе.
Сначала данные, которые я ввел в ES, а затем точный случай, который не сработал.
Сопоставление
POST /test
{
"mappings": {
"doc": {
"properties": {
"attributes": {
"type": "nested"
}
}
}
}
}
Тестовые данные
POST /test/doc/1 { "attributes": [{"id": 1}, {"id": 2}, {"id": 3}] }
POST /test/doc/2 { "attributes": [{"id": 3}, {"id": 5}] }
POST /test/doc/3 { "attributes": [{"id": 5}] }
Запрос
POST /test/doc/_search
{
"query": {
"nested": {
"path": "attributes",
"query": {
"constant_score": {
"filter": {
"bool": {
"must": [
{
"term": {
"attributes.id": 3
}
}
]
}
}
}
}
}
}
}
Результат, который работает (запрошен только один атрибут)
{
"took": 3,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"failed": 0
},
"hits": {
"total": 2,
"max_score": 1,
"hits": [
{
"_index": "test",
"_type": "doc",
"_id": "2",
"_score": 1,
"_source": {
"attributes": [
{
"id": 3
},
{
"id": 5
}
]
}
},
{
"_index": "test",
"_type": "doc",
"_id": "1",
"_score": 1,
"_source": {
"attributes": [
{
"id": 1
},
{
"id": 2
},
{
"id": 3
}
]
}
}
]
}
}
теперь я пытаюсь проверить 2 идентификатора атрибута и получаю пустой результат
Запрос (2 атрибута)
POST /test/doc/_search
{
"query": {
"nested": {
"path": "attributes",
"query": {
"constant_score": {
"filter": {
"bool": {
"must": [
{
"term": {
"attributes.id": 3
}
},
{
"term": {
"attributes.id": 5
}
}
]
}
}
}
}
}
}
}
Результат
{
"took": 2,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"failed": 0
},
"hits": {
"total": 0,
"max_score": null,
"hits": []
}
}
Как и в результате в одном запросе, я получил документ с идентификаторами атрибутов 3 и 5. Теперь у меня пустой результат.
Редактировать:
решением моей проблемы было не использовать вложенный объект!
POST /test
{
"mappings": {
"doc": {
"properties": {
"attributes": {
"type": "integer"
}
}
}
}
}
POST /test/doc/1
{ "attributes": [1, 2, 3] }
POST /test/doc/2
{ "attributes": [3, 5] }
POST /test/doc/3
{ "attributes": [5] }
POST /test/doc/_search
{
"query": {
"bool": {
"must": [
{
"term": {
"attributes": 3
}
},
{
"term": {
"attributes": 5
}
}
]
}
}
}
Ответ №1:
Это правильное поведение вложенных объектных отношений. Вложенные сопоставления сообщают, что вложенный объект индексируется как отдельные скрытые документы, и запрос выполняется для каждого вложенного объекта, а не для всей коллекции. Вы сказали в своем запросе, что найдите мне атрибут, где id = 3 и id = 5. Честно говоря, сценарий заключается в том, чтобы лучше взглянуть на отображение внутреннего объекта. В этой статье дается объяснение, когда следует использовать внутренний объект и вложенный объект, на основе очень похожего примера: https://www.elastic.co/guide/en/elasticsearch/guide/current/nested-objects.html
Ниже вы можете найти информацию о том, как хранятся данные для внутреннего объекта и для вложенного объекта. Часто люди используют вложенное сопоставление для сбора данных, но не знают последствий этого решения, поэтому я думаю, вам следует пересмотреть свой подход.
Внутренний объект сгенерирует что-то вроде этого:
attributes.id [1,2,3]
attributes.id [3,5]
attributes.id [5]
вложенный будет генерировать что-то вроде этого:
attributes.id [{"id": 1}, {"id": 2}, {"id": 3}]
attributes.id [{"id": 3}, {"id": 5}]
attributes.id [{"id": 5}]