Как сделать запрос по нескольким полям объекта в массиве документа в Elasticsearch?

Привет, я новичок в Elasticsearch. И я хочу запрашивать документы по значению его поля (тип: массив). Пример такой:

docx=people:[
{id:1,role:admin},
{id:2,role:other}
]
docy=people:[
{id:1,role:other},
{id:2,role:admin}
]

Мой запрос people.id:1 AND people.role:admin. Мой ожидаемый результат - только docx, но ES также возвращает docy. Я знаю, что это неправильно, но как я могу сделать это в ES. Итак, как строка запроса может фильтровать только такие документы, как docx. Спасибо!


person iamatsundere181    schedule 04.11.2020    source источник
comment
Можете ли вы показать более подробно, как выглядят ваши данные? Он мог бы работать с вложенными типами данных, но они снижают производительность.   -  person Evaldas Buinauskas    schedule 04.11.2020
comment
@EvaldasBuinauskas, спасибо, я добавил примечание об этом в свой ответ в очень хорошем блоге команды инженеров go-jek, пожалуйста, просмотрите его и не забудьте проголосовать, если вам понравился мой ответ: D   -  person user156327    schedule 04.11.2020


Ответы (1)


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

Но имейте в виду, что вложенный тип данных становится дорогостоящим, когда у вас большой набор данных и большое количество одновременных запросов, как описано в средний блог go-jek.

Следуйте этому блог, в котором подробно освещается ваша проблема.

Рабочий пример с правильным сопоставлением

Сопоставление индекса

{
    "mappings": {
        "properties": {
            "name" : {
             "type" :   "text"
            },
            "people": {
                "type": "nested"
            }
        }
    }
}

указать образец документа

{
    "name": "bar",
    "people": 
    [
        {
            "id": 1,
            "role": "other"
        },
        {
            "id": 2,
            "role": "admin"
        }
    ]
}

И второй образец документа

{
    "name": "foo",
    "people": 
    [
        {
            "id": 1,
            "role": "admin"
        },
        {
            "id": 2,
            "role": "other"
        }
    ]
}

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

{
    "query": {
        "nested": {
            "path": "people",
            "query": {
                "bool": {
                    "must": [
                        {
                            "match": {
                                "people.id": 1
                            }
                        },
                        {
                            "match": {
                                "people.role": "admin"
                            }
                        }
                    ]
                }
            }
        }
    }
}

И ожидаемый результат поиска

"hits": [
            {
                "_index": "matchphrase",
                "_type": "_doc",
                "_id": "1",
                "_score": 1.6931472,
                "_source": {
                    "name": "foo",
                    "people": [
                        {
                            "id": 1,
                            "role": "admin"
                        },
                        {
                            "id": 2,
                            "role": "other"
                        }
                    ]
                }
            }
        ]
person user156327    schedule 04.11.2020
comment
Я попробовал это, и результат, который я получил: не удалось создать запрос: [вложенный] вложенный объект по пути [люди] не имеет вложенного типа. Как это исправить? - person iamatsundere181; 04.11.2020
comment
@ iamatsundere181 вы использовали то же сопоставление, которое я разместил в своем ответе ?? - person user156327; 04.11.2020
comment
Я изменил, но он вернул такую ​​​​ошибку: невозможно изменить сопоставление объектов с не вложенного на вложенное. Должен ли я очистить и переиндексировать все данные, чтобы адаптировать это? - person iamatsundere181; 04.11.2020
comment
@ iamatsundere181, да, вам нужно создать новый индекс и переиндексировать все данные, чтобы адаптировать его :) - person user156327; 04.11.2020
comment
@ iamatsundere181 надеюсь, вам удалось решить проблему, создав новый индекс? пожалуйста, дайте мне знать и не забудьте проголосовать и принять ответ :) - person user156327; 05.11.2020
comment
@iamatsundere181 с нетерпением жду ваших отзывов. - person user156327; 05.11.2020
comment
Привет @Elasticsearch Ninja, долгое время твое решение идеально! Я отмечу его, но в моей ситуации мне нужно обойти, чтобы установить другое поле, которое используется для целей поиска. Бтв, большое спасибо! - person iamatsundere181; 09.11.2020
comment
@ iamatsundere181 большое спасибо за пометку ответа, рад, что был полезен и лучше поздно, чем никогда :) - person user156327; 09.11.2020