как вернуть все документы, которые имеют подмножество входного массива в OpenSearch
У меня есть документ с заданной структурой:
{ "name" : "WF1", "myIndex" : [3, 4, 5] }
Допустим, у меня есть 4 таких записи -
{ "name" : "WF1", "myIndex" : [3, 4, 5] }
{ "name" : "WF2", "myIndex" : [6, 7, 8] }
{ "name" : "WF3", "myIndex" : [9, 10, 11] }
{ "name" : "WF4", "myIndex" : [3, 6, 9] }
Если я стреляю ниже запроса «термин»:
GET myIndex/_search
{
"query": {
"terms": {
"qualsIndex": [
3, 6, 9, 20
]
}
}
}
Он возвращает все 4 записи. Принимая во внимание, что я хочу вернуть только запись с 3,6, 9, т.е. только WF4. По сути, мне нужен результирующий документ, в котором передано подмножество входных данных.
Примечание. Я могу настроить структуру своего документа, чтобы добиться этого. возможно ли это в OpenSearch?
2 ответа
TLD;
Вы можете добиться этого с помощью запроса набора терминов .
Чтобы понять
Пример сопоставления:
{
"mappings": {
"properties": {
"name": {
"type": "keyword"
},
"myIndex": {
"type": "keyword"
},
"required_matches": {
"type": "long"
}
}
}
}
Пример запроса:
{
"query": {
"terms_set": {
"myIndex": {
"terms": [3, 6, 9, 20],
"minimum_should_match_field": "required_matches"
}
}
}
}
В твоем случае,
required_matches
должен быть индексирован как количество элементов массива myIndex.
Воспроизвести
Вот полностью рабочий пример:
Прежде всего установка:
DELETE /72004393/
PUT /72004393/
{
"mappings": {
"properties": {
"myIndex": {
"type": "keyword"
},
"name": {
"type": "text"
}
}
}
}
POST _bulk
{"index":{"_index":"72004393"}}
{"name":"WF1","myIndex":["3","4","5"]}
{"index":{"_index":"72004393"}}
{"name":"WF2","myIndex":["6","7","8"]}
{"index":{"_index":"72004393"}}
{"name":"WF3","myIndex":["9","10","11"]}
{"index":{"_index":"72004393"}}
{"name":"WF4","myIndex":["3","6","9"]}
Запрос:
GET /72004393/_search
{
"query": {
"terms_set": {
"myIndex": {
"terms": [ "3", "6", "9", "20" ],
"minimum_should_match_script": {
"source": "3"
}
}
}
}
}
Дает:
{
...
"hits" : {
...
"max_score" : 2.859232,
"hits" : [
{
"_index" : "72004393",
"_id" : "LqOQZ4ABOgujegeQ2gfV",
"_score" : 2.859232,
"_source" : {
"name" : "WF4",
"myIndex" : ["3","6","9"]
}
}
]
}
}
Другой пример:
PUT test
{
"mappings": {
"properties": {
"myIndex": {
"type": "keyword"
},
"name": {
"type": "text"
},
"required_matches": {
"type": "long"
}
}
}
}
POST _bulk
{"index":{"_index":"test"}}
{"name":"WF1","myIndex":["3","4","5"], "required_matches": 3}
{"index":{"_index":"test"}}
{"name":"WF2","myIndex":["6","7","8"], "required_matches": 3}
{"index":{"_index":"test"}}
{"name":"WF3","myIndex":["9","10","11"], "required_matches": 3}
{"index":{"_index":"test"}}
{"name":"WF4","myIndex":["3","6","9"], "required_matches": 3}
{"index":{"_index":"test"}}
{"name":"WF5","myIndex":["3","6","9", "15", "20"], "required_matches": 5}
{"index":{"_index":"test"}}
{"name":"WF6","myIndex":["3","6","9", "15"], "required_matches": 4}
Запрос:
GET test/_search
{
"query": {
"terms_set": {
"myIndex": {
"terms": ["3", "6", "9"],
"minimum_should_match_field": "required_matches"
}
}
}
}
Приведенный выше запрос будет соответствовать только WF4, поскольку его required_match равен 3, а требуемые совпадения WF5 И WF6 — 4 и 5.
Если вы обновите термины в запросе на
["3", "6", "9", "15"]
он будет соответствовать как WF4, так и WF5, и если вы обновите его до
["3", "6", "9", "15", "20"]
он будет соответствовать WF4, WF5, WF6.
TLDR;
Насколько мне известно, ни в ElasticSearch, ни в OpenSearch нет решения. Но я думаю, вы можете взломать его, используя
number
в качестве
words
Взлом
Индексация документа с полем
myIndex
в виде строки чисел. Позже я могу найти эти числа, используя запрос соответствия и такой параметр, как
minimum_should_match
.
DELETE 72004393
POST _bulk
{"index":{"_index":"72004393"}}
{"name":"WF1","myIndex":"3 4 5"}
{"index":{"_index":"72004393"}}
{"name":"WF2","myIndex":"6 7 8"}
{"index":{"_index":"72004393"}}
{"name":"WF3","myIndex":"9 10 11"}
{"index":{"_index":"72004393"}}
{"name":"WF4","myIndex":"3 6 9"}
GET /72004393/_search
{
"query": {
"match": {
"myIndex": {
"query": "3 6 9 20",
"minimum_should_match": 3
}
}
}
}
Даст вам что-то вроде этого:
{
...
"hits" : {
...
"max_score" : 2.0794413,
"hits" : [
{
"_index" : "72004393",
"_id" : "xaMuYoABOgujegeQJgZr",
"_score" : 2.0794413,
"_source" : {
"name" : "WF4",
"myIndex" : "3 6 9"
}
}
]
}
}
Это не идеально и может привести к некоторым крайним случаям, но это самое близкое к «решению», которое я мог бы найти.