Как получить точное совпадение фразы с помощью BleveSearch?
Я ищу синонимы для конкретной фразы из набора данных. У меня есть 2 файла JSON, в которых хранятся данные, состоящие из синонимов для да и нет. Если я запрашиваю "неинтересно", в результате даются и фразы, и синонимы "да" и "нет", ожидаемый результат - просто нет фраз / синонимов.
ен-ген-yes.json
{
"tag":"en-gen-yes",
"phrases": [
"yes",
"yeah",
"sure",
"suits me",
"interested"
]
}
ен-ген-no.json
{
"tag":"en-gen-no",
"phrases": [
"no",
"nope",
"not sure",
"does not suits me",
"not interested"
]
}
код запроса
query := bleve.NewMatchPhraseQuery("not interested")
req := bleve.NewSearchRequest(query)
req.Fields = []string{"phrases"}
searchResults, err := paraphraseIndex.Search(req)
if err != nil {
log.Fatal(err)
}
if searchResults.Hits.Len() == 0 {
fmt.Println("No matches found")
} else {
for i := 0; i < searchResults.Hits.Len(); {
hit := searchResults.Hits[i]
fmt.Printf("%s\n", hit.Fields["phrases"])
i = i + 1
}
}
Результат приходит как
[Нет, не уверен, не подходит мне не интересно] [да, да, конечно, мне интересно]
Ожидаемый результат только
[Нет, не уверен, не подходит мне не интересно]
1 ответ
Причина, по которой они совпадают, заключается в том, что используемый вами MatchPhraseQuery будет анализировать условия поиска. Вы не показывали здесь IndexMapping, поэтому я не уверен, но я предполагаю, что вы используете "стандартный" анализатор. Этот анализатор удаляет английские стоп-слова, и здесь определяется список английских стоп-слов:
https://github.com/blevesearch/bleve/blob/master/analysis/lang/en/stop_words_en.go#L281
Таким образом, это означает, что когда вы делаете MatchPhraseQuery для "неинтересных", вы в конечном итоге просто ищете "заинтересованные". И этот термин также входит в ваш список "да" синонимов.
Стоит отметить, что существует вариант под названием PhraseQuery (без соответствия), который выполняет точное соответствие. И хотя это не удалит слово "не" во время поиска, оно все равно не найдет совпадение. И причина в том, что слово "not" также было удалено во время индексации, поэтому точное совпадение "not заинтересованных" не нашло бы совпадений (ни да, ни нет).
Решение заключается в настройке пользовательского анализатора, который либо не удаляет стоп-слова, либо использует список пользовательских стоп-слов, который не содержит слова "not". Если вы сделаете это и будете использовать его как для индексации, так и для поиска, используемый вами запрос должен начать работать правильно.