Как учесть порядок слов, но не требовать, чтобы все искомые слова существовали в документе для запроса Match_phrase ElasticSearch? - PullRequest
0 голосов
/ 17 июня 2020

Предположим, что в моем индексе есть два документа:

  1. «получите мои деньги»
  2. «мои деньги получите»

Когда я обычный запрос соответствия для "получить мои деньги", оба документа совпадают правильно, но получают равные оценки. Однако я хочу, чтобы порядок слов имел значение при подсчете очков. Другими словами, я хочу, чтобы «получить мои деньги» имели более высокий балл.

Итак, я попытался поместить свой запрос на сопоставление в предложение must в запросе типа bool и включил match_phrase (с той же строкой запроса). Кажется, что это правильно подсчитывает попадания, пока я не выполню поиск с запросом «как мне получить свои деньги». В этом случае запрос match_phrase, похоже, не соответствует, и совпадения возвращаются с равными оценками снова.

Как я могу построить свой индекс / запрос, чтобы он учитывал порядок слов, но не требовал всех искомые слова существуют в документе?

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

PUT test-index
{
  "mappings": {
      "properties" : {
        "keyword" : {
          "type" : "text",
          "similarity": "boolean"
        }
      }
    }
}
POST test-index/_doc/
{
    "keyword" : "get my money"
}
POST test-index/_doc/
{
    "keyword" : "my money get here"
}

Запрос «Как мне получить деньги?» - Не Не работает должным образом

GET /test-index/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "keyword": "how do i get my money"
          }
        }
      ],
      "should": [
        {
          "match_phrase": {
            "keyword": {
              "query": "how do i get my money"
            }
          }
        }
      ]
    }
  }
}

Результаты (оба документа имеют одинаковые оценки)

{
  "took" : 2,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 2,
      "relation" : "eq"
    },
    "max_score" : 3.0,
    "hits" : [
      {
        "_index" : "test-index",
        "_type" : "_doc",
        "_id" : "6Xy8wXIB3NtI_ttPGBoV",
        "_score" : 3.0,
        "_source" : {
          "keyword" : "get my money"
        }
      },
      {
        "_index" : "test-index",
        "_type" : "_doc",
        "_id" : "6ny8wXIB3NtI_ttPGBpV",
        "_score" : 3.0,
        "_source" : {
          "keyword" : "my money get here"
        }
      }
    ]
  }
}

Редактировать 1

Как @gibbs предложили, давайте удалим "similarity": "boolean". Ниже представлен более упрощенный и конкретный вопрос. Мы пытаемся найти на это ответ.

Удалено "similarity": "boolean"

PUT test-index
{
  "mappings": {
      "properties" : {
        "keyword" : {
          "type" : "text"
        }
      }
    }
}
POST test-index/_doc/
{
    "keyword": "get my money"
}
POST test-index/_doc/
{
    "keyword": "my money get here"
}

Как заставить этот запрос возвращать результаты? теперь это не так. Можно ли вернуть результаты, если все искомые слова не существуют в документе при использовании match_phrase?

GET /test-index/_search
{
  "query": {
    "bool": {
      "should": [
        {
          "match_phrase": {
            "keyword": {
              "query": "how do I get my money"
            }
          }
        }
      ]
    }
  }
}

Edit 2

В нашем случае мы не можем использовать BM25 (TF / IDF), потому что это испортит наши результаты.

POST test-index/_doc
{
  "keyword": "get my money, claim, distribution, getting started"
}

POST test-index/_doc 
{
  "keyword": "my money get here"
}
GET /test-index/_search 
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "keyword": "how do I get my money"
          }
        }
      ]
    }
  }
}

Результаты

{
  "took" : 16,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 2,
      "relation" : "eq"
    },
    "max_score" : 0.6156533,
    "hits" : [
      {
        "_index" : "test-index",
        "_type" : "_doc",
        "_id" : "JnxCw3IB3NtI_ttPBjQv",
        "_score" : 0.6156533,
        "_source" : {
          "keyword" : "my money get here"
        }
      },
      {
        "_index" : "test-index",
        "_type" : "_doc",
        "_id" : "x3xSw3IB3NtI_ttP1DUi",
        "_score" : 0.49206492,
        "_source" : {
          "keyword" : "get my money, claim, distribution, getting started"
        }
      }
    ]
  }
}

В этом сценарии мои деньги получаются набирает больше, чем предполагалось получает мои деньги из-за TF / IDF. Таким образом, у нас не может быть того, где подсчет баллов будет зависеть от количества совпадающих документов, длины поля и т. Д. c.

Извините за очень длинный вопрос. Итак, вернемся к моему исходному вопросу Как я могу построить свой индекс / запрос так, чтобы он учитывал порядок слов, но не требовал, чтобы все искомые слова существовали в документе?

1 Ответ

0 голосов
/ 17 июня 2020

Проблема связана с вашим параметром similarity.

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

Ссылка

Вам следует использовать другие параметры сходства (BM25), чтобы получить более высокие оценки.

Я удалил параметр similarity из вашего сопоставления и проиндексировал те же данные. Используется параметр по умолчанию similarity.

Оценка следующая.

{
    "took": 1069,
    "timed_out": false,
    "_shards": {
        "total": 1,
        "successful": 1,
        "skipped": 0,
        "failed": 0
    },
    "hits": {
        "total": {
            "value": 2,
            "relation": "eq"
        },
        "max_score": 0.5809142,
        "hits": [
            {
                "_index": "test-index",
                "_type": "_doc",
                "_id": "WpaHwnIBa8oXh9OgX4Hb",
                "_score": 0.5809142,
                "_source": {
                    "keyword": "get my money"
                }
            },
            {
                "_index": "test-index",
                "_type": "_doc",
                "_id": "W5aHwnIBa8oXh9OgeYG9",
                "_score": 0.5167642,
                "_source": {
                    "keyword": "my money get here"
                }
            }
        ]
    }
}
...