ElasticSearch: shingles - соответствует фразе, если поле содержит точный токен

Я новичок с упругим поиском и у меня проблемы со следующим сценарием:

  1. Давайте рассмотрим, у меня есть 2 документа, который содержит только одно поле "текст"
    1. "текст": "токен1 токен4"
    2. "текст": "токен2 токен3"
    3. "текст": "токен4 токен5"
  2. И, следуя тексту запроса "token1 token2 token3 token4 token5", я хочу найти только документы 2 и 3

Мне нужно что-то похожее на фильтр shingles, который будет создавать следующие токены из запроса:

["token1 token2", "token2 token3", "token3 token4", "token4 token5"]

И будет точно соответствовать этим токенам, поэтому токены "token2 token3" и "token4 token5" будут соответствовать документу

Заранее спасибо!

1 ответ

Это можно сделать, используя фильтр shingle и сделав output_unigrams false (это предотвратит генерацию одиночного токена). Создайте свой индекс, как это

PUT shingle_index
{
  "settings": {
    "analysis": {
      "analyzer": {
        "shingle_analyzer": {
          "tokenizer": "standard",
          "filter": [
            "shingle_filter",
            "lowercase"
          ]
        }
      },
      "filter": {
        "shingle_filter":{
          "type" : "shingle",
          "max_shingle_size" : 2,
          "min_shingle_size" : 2,
          "output_unigrams" : false,
          "output_unigrams_if_no_shingles" : true
        }
      }
    }
  },
  "mappings": {
    "mytype":{
      "properties": {
        "text" : {
          "type": "string",
          "analyzer": "shingle_analyzer"
        }
      }
    }
  }
}

Индексируйте некоторые образцы документов.

POST /shingle_index/mytype/_bulk
{"index":{"_id":5}}
{"text":"token1 token4"}
{"index":{"_id":3}}
{"text":"token2 token3"}
{"index":{"_id":2}}
{"text":"token4 token5"}

Тогда простой запрос на совпадение даст вам желаемый результат.

GET shingle_index/_search
{
  "query": {
    "match": {
      "text": "token1 token2 token3 token4"
    }
  }
}
Другие вопросы по тегам