NEST не возвращает значения для точного поиска
Я пытаюсь создать динамический запрос, используя NEST, который находится под
string product = "goldpgl";
string agencyid = "1123";
ISearchResponse <ProductModel> res = client().Search<ProductModel>(s => s
.Index("proddata")
.From(0)
.Size(100)
.Query(q =>
+q.Term(p => p.product, product) &&
+q.Term(p => p.agencyid, agencyid)));
Если я пройду, product value = "GoldPGL"
[NB~ Реальное значение в индексе], я не могу найти результат.
Однако, если я передаю значение в нижнем регистре, например "goldpgl", это сработает.
Кроме того, это не работает для таких значений, как "Gold - PGL" или "НЕКОТОРЫЙ ДРУГОЙ КРЕДИТ".
Мой POCO находится под
public class ProductModel
{
public string product { get; set; }
public string agencyid { get; set; }
}
Что не так и как это исправить?
1 ответ
Поскольку вы не предоставили сопоставление и поисковый запрос, я предполагаю, что это происходит, потому что вы используете запрос термина, а не запрос соответствия.
Термин запросы не анализируются, это означает, что все, что вы ввели в поисковый запрос, будет сопоставляться с токенами в индексе. И по умолчанию все текстовые поля в Elasticsearch используют стандартный анализатор, который переводит токены в нижний регистр. следовательноGoldPGL
не совпадает пока goldpgl
соответствует вашему запросу термина.
Пока match
запрос, как объяснено, официальный документ - это анализируемый запрос, и тот же анализатор применяется к поисковому запросу, который применяется во время индексации, следовательно GoldPGL
так же как goldpgl
конвертировано в goldpgl
и оба запроса соответствуют документам, и то же самое с Gold - PGL
который также совпадает и проверяется мной.
API Analyze очень удобен для устранения проблем такого типа, когда поисковый запрос не соответствует проиндексированным токенам и один пример того, какGOLDPGL
будет проанализировано показано ниже:
POST /_analyze
{
"text": "GOLDPGL",
"analyzer" : "standard"
}
{ "token": "goldpgl",}
{
"text": "GOLD - PGL",
"analyzer" : "standard"
}
{
"token": "gold",
"start_offset": 0,
"end_offset": 4,
"type": "<ALPHANUM>",
"position": 0
},
{
"token": "pgl",
"start_offset": 7,
"end_offset": 10,
"type": "<ALPHANUM>",
"position": 1
}
Я воспроизвел вашу проблему и, поскольку я не знаком с NEST, показал ваш пример с использованием REST API.
Индекс Def
ПОСЛЕ /
{
"mappings": {
"properties": {
"product": {
"type": "text"
}
}
}
}
Индексируйте некоторые документы
POST //_doc/1
{
"product": "GoldPGL"
}
Индексировать 2-й документ
{
"product": "Gold - PGL"
}
Теперь поисковый запрос, использующий запрос термина (как показано в вашем примере), не возвращает никакого результата (когда GoldPGL
используется)
{
"query": {
"term": {
"product": {
"value": "GoldPGL"
}
}
}
}
При использовании goldgpl
, дает результат
{
"query": {
"term": {
"product": {
"value": "goldpgl"
}
}
}
}
Результат
"hits": [
{
"_index": "so-term-nest",
"_type": "_doc",
"_id": "1",
"_score": 0.8025915,
"_source": {
"product": "GoldPGL"
}
}
]
Решение (используйте запрос на совпадение)
{
"query": {
"match" : {
"product" : {
"query" : "GoldPGL"
}
}
}
}
и это возвращает результаты
"hits": [
{
"_index": "so-term-nest",
"_type": "_doc",
"_id": "1",
"_score": 0.8025915,
"_source": {
"product": "GoldPGL"
}
}
]