Анализ проблемы
Давайте разберем вашу проблему в следующих подзадачах:
- (P1) Проверьте, присутствуют ли все термины, представленные в массиве, либо в
tags.id
, либо tags.related
. Это может быть далее разложено на:
- (P1.1) Проверьте, присутствует ли в all термины, указанные в массиве, в поле
- (P1.2) Проверьте, распространяется ли all термины, представленные в массиве, на разные поля
- (P2) Присвойте более высокий балл тем документам, имеющим любое из предоставленных условий, как
tags.id
Решение
Чтобы решить (P1.1) , вы можете использовать запрос terms_set
, доступный в Elasticsearch v6.6 (см. документация ).
Чтобы решить (P1.2) , я бы скопировал все значения tags.id
и tags.related
в новое настраиваемое поле с именем, например, tags.all
. Это может быть достигнуто с помощью свойства copy_to
следующим образом:
{
"mappings": {
"_doc": {
"properties": {
"tags": {
"properties": {
"id": {
"type": "long",
"copy_to": "tags.all"
},
"related": {
"type": "long",
"copy_to": "tags.all"
}
}
}
}
}
}
}
Затем, чтобы решить (P1) , вы можете выполнить свой запрос terms_set
для tags.all
. Например.,
{
"query": {
"terms_set": {
"tags.all": {
"terms": [ 9, 8 ],
"minimum_should_match_script": {
"source": "2"
}
}
}
}
}
Наконец, чтобы решить (P2) , вы можете создать логический запрос should
, который включает (i) запрос terms_set
, описанный выше, (ii) запрос terms
против tags.id
только, который имеет более высокий коэффициент усиления. То есть.,
{
"query": {
"bool": {
"should": [
{
"terms_set": {
"tags.all": {
"terms": [ 9, 8 ],
"minimum_should_match_script": {
"source": "2"
}
}
}
},
{
"terms": {
"tags.id": {
"value": [ 9, 8 ],
"boost": 2
}
}
}
]
}
}
}