ElasticSearch: shingles - соответствует фразе, если поле содержит точный токен
Я новичок с упругим поиском и у меня проблемы со следующим сценарием:
- Давайте рассмотрим, у меня есть 2 документа, который содержит только одно поле "текст"
- "текст": "токен1 токен4"
- "текст": "токен2 токен3"
- "текст": "токен4 токен5"
- И, следуя тексту запроса "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"
}
}
}