Результат сортировки на основе динамических терминов - PullRequest
0 голосов
/ 10 апреля 2019

Представьте, что у меня есть индекс со следующими тремя документами, представляющими изображения и их цвета.

[
    {
        "id": 1,
        "intensity": {
            "red": 0.6,
            "green": 0.1,
            "blue": 0.3
        }
    },
    {
        "id": 2,
        "intensity": {
            "red": 0.5,
            "green": 0.6,
            "blue": 0.0
        }
    },
    {
        "id": 3,
        "intensity": {
            "red": 0.98,
            "green": 0.0,
            "blue": 0.0
        }
    }

]

Если пользователь хочет «красное изображение» (выбранное в раскрывающемся списке или в «облаке тегов»), очень удобно выполнять запрос диапазона по плавающим значениям (возможно, intensity.red > 0.5). Я также могу использовать оценку этого запроса, чтобы получить «самое красное» изображение, получившее самый высокий рейтинг. Однако, если я хотел бы предложить поиск в свободном тексте, это становится сложнее. Мое решение заключается в том, чтобы индексировать документы следующим образом (например, использовать if color > 0.5 then append(colors, color_name) во время индексации):

[
    {
        "id": 1,
        "colors": ["red"]
    },
    {
        "id": 2,
        "colors": ["green", "red"]
    }
    {
        "id": 3,
        "colors": ["red"]
    }
]

Теперь я могу использовать query_string или match в поле цветов и затем искать "red", но внезапно я потерял свои возможности ранжирования. ID 3 намного более красный, чем ID 1 (0.98 против 0.6), но результат будет аналогичным?

Мой вопрос: могу ли я взять торт и съесть его тоже?

Одно решение, которое я вижу, состоит в том, чтобы иметь один индекс, который превращает свободный текст в «ключевые слова», которые я позже использую в реальном поиске.

POST image_tag_index/_search {query: "redish"} -> [ "red" ]
POST images/_search {query: {"red" > 0.5}} -> [ {id: 1}, {id: 3}]

Но тогда мне нужно запустить два поиска для каждого поиска, но, может быть, это единственный вариант?

1 Ответ

1 голос
/ 10 апреля 2019

Вы можете использовать вложенный тип данных вместе с function_score запросом, чтобы получить желаемый результат.

Вам необходимо изменить способ хранения данных изображения. Отображение будет следующим:

PUT test
{
  "mappings": {
    "_doc": {
      "properties": {
        "id": {
          "type": "integer"
        },
        "image": {
          "type": "nested",
          "properties": {
            "color": {
              "type": "text",
              "fields": {
                "keyword": {
                  "type": "keyword"
                }
              }
            },
            "intensity": {
              "type": "float"
            }
          }
        }
      }
    }
  }
}

Индексируйте данные изображения, как показано ниже:

PUT test/_doc/1
{
  "id": 1,
  "image": [
    {
      "color": "red",
      "intensity": 0.6
    },
    {
      "color": "green",
      "intensity": 0.1
    },
    {
      "color": "blue",
      "intensity": 0.3
    }
  ]
}

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

Теперь, когда пользователь ищет red, запрос должен быть построен следующим образом:

{
  "query": {
    "bool": {
      "must": [
        {
          "nested": {
            "path": "image",
            "query": {
              "function_score": {
                "query": {
                  "bool": {
                    "must": [
                      {
                        "match": {
                          "image.color": "red"
                        }
                      },
                      {
                        "range": {
                          "image.intensity": {
                            "gt": 0.5
                          }
                        }
                      }
                    ]
                  }
                },
                "field_value_factor": {
                  "field": "image.intensity",
                  "modifier": "none",
                  "missing": 0
                }
              }
            }
          }
        }
      ]
    }
  }
}

Вы можете видеть в приведенном выше запросе, что я использовал значение поля image.intensity для вычисления оценки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...