Сопоставить массив с массивом из ELASTICSEARCH

У меня есть индекс в ES, где я хранил свой каталог. Документы представляют собой смесь типа строки и массива (пример показан ниже):

{
  "_index" : "catalog",
  "_type" : "_doc",
  "_id" : "N1234",
  "_score" : 1.0,
  "_source" : {
    "product_id" : "1234",
    "name" : "Multifunctional Soapbox Hanging",
    "model" : "HS-11",
    "image" : "catalog/1.jpg",
    "size" : [
      "43",
      "44",
      "45"
    ],
    "color" : [
      "66",
      "67"
    ],
    "tag" : [
      "Soap Dish Rack Bathroom Essentials",
      "Plastic Bathroom Essentials",
      "Adhesive Bathroom Essentials",
      "Smart Accessories Bathroom Essentials",
      "Any Bathroom Essentials",
      "Brown Bathroom Essentials",
      "Bathroom Accessories Bathroom Essentials",
      "Bathroom Essentials"
    ],
    "language_id" : "1",
    "status" : "7",
    "date_added" : "2021-02-06 14:29:37"
  }
}

Все документы имеют одинаковую структуру. Я хочу запросить свой индекс для похожих продуктов на основе полей Color и Tag. Означает, что если я передам color = 66 и Tag = [ARRAY_OF_VALUES], он должен вернуть мне наиболее похожие продукты, отсортированные по количеству баллов, которые могут содержать одинаковый ЦВЕТ или максимальное количество совпадающих ТЕГОВ.

Я пробовал BOOL запрос с Should или Must, но не лучше результатов.

Я понятия не имею, как запрашивать массив, поскольку и цвет, и теги являются массивами. Должен ли я передавать параметры TAGS в виде массива или отдельных значений и делать отдельные запросы match?

Запрос, который я пробовал (от @ESCoder):

"query": {
"bool": {
  "must": [
    {
      "terms": {
        "color": [
          "40" //code of blue color
        ]
      }
    }
  ],
  "should": [
    {
      "terms": {
        "tag": [
          "Casual Dresses",
          "Round Neck Dresses",
          "Short Sleeves Dresses",
          "Blue Dresses"
        ]
      }
    }
  ]
}

}

Ожидаемый результат:

Все товары, содержащие одинаковые color и максимально похожие tag , отсортированные по количеству баллов

{
  "_index" : "catalog",
  "_type" : "_doc",
  "_id" : "N624121",
  "_score" : 39.43454,
  "_source" : {
    "color" : [
      "40"
    ],
    "size" : [
      "47",
      "48",
      "50",
      "51"
    ],
    "product_id" : "62412",
    "name" : "Girls Short Sleeve Fashion Short Dress - Blue",
    "model" : "LYQ001",
    "tag" : [
      "Casual Dresses",
      "Body Fitted Dresses",
      "Short Gown Dresses",
      "Slip Dress Dresses",
      "Blue Dresses"
    ]
  }
},
{
  "_index" : "catalog",
  "_type" : "_doc",
  "_id" : "N624151",
  "_score" : 39.046432,
  "_source" : {
    "color" : [
      "40"
    ],
    "size" : [
      "47",
      "48",
      "50",
      "51"
    ],
    "product_id" : "62415",
    "name" : "Girls Short Sleeve Fashion Short Dress - Sky Blue",
    "model" : "LYQ001",
    "tag" : [
      "Casual Dresses",
      "Body Fitted Dresses",
      "Short Sleeves Dresses",
      "Slip Dress Dresses",
      "Sky Blue Dresses"
    ]
  }
},
{
  "_index" : "catalog",
  "_type" : "_doc",
  "_id" : "N624111",
  "_score" : 38.569298,
  "_source" : {
    "color" : [
      "40"
    ],
    "size" : [
      "47",
      "48",
      "50",
      "51"
    ],
    "product_id" : "62411",
    "name" : "Girls Short Sleeve Fashion Short Dress - Navy blue",
    "model" : "LYQ001",
    "tag" : [
      "Casual Dresses",
      "Body Fitted Dresses",
      "Round Neck Dresses",
      "Slip Dress Dresses",
      "Black Dresses"
    ]
  }
},
{
  "_index" : "catalog",
  "_type" : "_doc",
  "_id" : "N624131",
  "_score" : 37.646904,
  "_source" : {
    "color" : [
      "40"
    ],
    "size" : [
      "47",
      "48",
      "50",
      "51"
    ],
    "product_id" : "62413",
    "name" : "Girls Short Sleeve Fashion Short Dress - light blue",
    "model" : "LYQ001",
    "tag" : [
      "Casual Dresses",
      "Body Fitted Dresses",
      "Short Gown Dresses",
      "Slip Dress Dresses",
      "light blue Dresses"
    ]
  }
},
{
  "_index" : "catalog",
  "_type" : "_doc",
  "_id" : "N624141",
  "_score" : 37.02933,
  "_source" : {
    "color" : [
      "233"
    ],
    "size" : [
      "47",
      "48",
      "50",
      "51"
    ],
    "product_id" : "62414",
    "name" : "Girls Short Sleeve Fashion Short Dress - Wine",
    "model" : "LYQ001",
    "tag" : [
      "Casual Dresses",
      "Body Fitted Dresses",
      "Round Neck Dresses",
      "Short Sleeves Dresses",
      "Wine Red Dresses"
    ]
  }
},
{
  "_index" : "catalog",
  "_type" : "_doc",
  "_id" : "N624161",
  "_score" : 36.39569,
  "_source" : {
    "color" : [
      "84"
    ],
    "size" : [
      "47",
      "48",
      "50",
      "51"
    ],
    "product_id" : "62416",
    "name" : "Girls Short Sleeve Fashion Short Dress - Rose",
    "model" : "LYQ001",
    "tag" : [
      "Casual Dresses",
      "Body Fitted Dresses",
      "Short Gown Dresses",
      "Slip Dress Dresses",
      "Blue Dresses"
    ]
  }
}

person Muhammad Hashir Anwaar    schedule 18.04.2021    source источник
comment
не могли бы вы поделиться ожидаемым результатом поиска?   -  person ESCoder    schedule 18.04.2021
comment
@ESCoder Обновлено ... Пожалуйста, проверьте   -  person Muhammad Hashir Anwaar    schedule 18.04.2021


Ответы (1)


Вы можете использовать запрос терминов для поиска нескольких значений.

Запрос терминов возвращает документ с точными терминами в указанном поле (здесь tag).

Если вы явно не определили какое-либо сопоставление, вам необходимо добавить .keyword в поле tag. При этом вместо стандартного анализатора используется анализатор ключевых слов (обратите внимание на ключевое слово .keyword после поля tag).

Попробуйте выполнить приведенный ниже запрос

    {
  "query": {
    "bool": {
      "must": [
        {
          "terms": {
            "color": [
              "40" //code of blue color
            ]
          }
        },
        {
          "terms": {
            "tag.keyword": [
              "Casual Dresses",
              "Round Neck Dresses",
              "Short Sleeves Dresses",
              "Blue Dresses"
            ]
          }
        }
      ]
    }
  }
}

В результатах поиска будут все документы с оценкой 2,0


Но если вы хотите сортировать на основе оценки, вам нужно использовать предложение bool/should вместе с запросом term.

{
  "query": {
    "bool": {
      "must": [
        {
          "terms": {
            "color": [
              "40" //code of blue color
            ]
          }
        }
      ],
      "should": [
        {
          "term": {
            "tag.keyword": "Casual Dresses"
          }
        },
        {
          "term": {
            "tag.keyword": "Round Neck Dresses"
          }
        },
        {
          "term": {
            "tag.keyword": "Short Sleeves Dresses"
          }
        },
        {
          "term": {
            "tag.keyword": "Blue Dresses"
          }
        }
      ],
      "minimum_should_match": 1
    }
  }
}

Результат поиска будет

"hits": [
      {
        "_index": "67148091",
        "_type": "_doc",
        "_id": "1",
        "_score": 2.640676,
        "_source": {
          "color": [
            "40"
          ],
          "size": [
            "47",
            "48",
            "50",
            "51"
          ],
          "product_id": "62412",
          "name": "Girls Short Sleeve Fashion Short Dress - Blue",
          "model": "LYQ001",
          "tag": [
            "Casual Dresses",
            "Body Fitted Dresses",
            "Short Gown Dresses",
            "Slip Dress Dresses",
            "Blue Dresses"
          ]
        }
      },
      {
        "_index": "67148091",
        "_type": "_doc",
        "_id": "2",
        "_score": 2.640676,
        "_source": {
          "color": [
            "40"
          ],
          "size": [
            "47",
            "48",
            "50",
            "51"
          ],
          "product_id": "62415",
          "name": "Girls Short Sleeve Fashion Short Dress - Sky Blue",
          "model": "LYQ001",
          "tag": [
            "Casual Dresses",
            "Body Fitted Dresses",
            "Short Sleeves Dresses",
            "Slip Dress Dresses",
            "Sky Blue Dresses"
          ]
        }
      },
      {
        "_index": "67148091",
        "_type": "_doc",
        "_id": "3",
        "_score": 2.640676,
        "_source": {
          "color": [
            "40"
          ],
          "size": [
            "47",
            "48",
            "50",
            "51"
          ],
          "product_id": "62411",
          "name": "Girls Short Sleeve Fashion Short Dress - Navy blue",
          "model": "LYQ001",
          "tag": [
            "Casual Dresses",
            "Body Fitted Dresses",
            "Round Neck Dresses",
            "Slip Dress Dresses",
            "Black Dresses"
          ]
        }
      },
      {
        "_index": "67148091",
        "_type": "_doc",
        "_id": "4",
        "_score": 1.1101605,
        "_source": {
          "color": [
            "40"
          ],
          "size": [
            "47",
            "48",
            "50",
            "51"
          ],
          "product_id": "62413",
          "name": "Girls Short Sleeve Fashion Short Dress - light blue",
          "model": "LYQ001",
          "tag": [
            "Casual Dresses",
            "Body Fitted Dresses",
            "Short Gown Dresses",
            "Slip Dress Dresses",
            "light blue Dresses"
          ]
        }
      }
    ]
person ESCoder    schedule 18.04.2021
comment
@Muhammad Hashir Anwaar, пожалуйста, просмотрите ответ и дайте мне знать, решит ли это вашу проблему? - person ESCoder; 18.04.2021
comment
@Muhammad Hashir Anwaar, в ожидаемом результате поиска нет документа с "color"=66? Каковы условия, на которых вы хотите запрос? Это условие color = 66 and Tag = [ARRAY_OF_VALUES] ? - person ESCoder; 18.04.2021
comment
Сэр, если вы ответите, мне будет немного проще... Я только что изменил второй запрос term в массиве should. Теперь он возвращает новые все продукты одного цвета, независимо от того, что я передаю, и соответствует только нескольким тегам из заданного массива. - person Muhammad Hashir Anwaar; 18.04.2021
comment
@MuhammadHashirAnwaar рад, что это сработало для вас :-) Итак, вы получили ожидаемый результат поиска? - person ESCoder; 18.04.2021
comment
немного сэр. в последний раз, пожалуйста, взгляните на раздел QUERY I TIRED и разделы Result... я также хочу сопоставить Tags, но пока я получаю совпадение только по цвету. может быть из-за SHOULD - person Muhammad Hashir Anwaar; 18.04.2021
comment
@MuhammadHashirAnwaar Конечно, позвольте мне проверить - person ESCoder; 18.04.2021
comment
@MuhammadHashirAnwaar, пожалуйста, просмотрите обновленный запрос в моем ответе и дайте мне знать, решит ли это вашу проблему? - person ESCoder; 18.04.2021
comment
Все тот же результат, сэр... Я думаю, следует игнорировать теги, а также _score всегда = 1.0 - person Muhammad Hashir Anwaar; 18.04.2021
comment
Давайте продолжим это обсуждение в чате. - person ESCoder; 18.04.2021