Запрос Elasticsearch Nest для обрезки пробелов при сравнении полей с предоставленным значением
Я работаю с Nest API для упругого поиска и ищу решение, в котором мы могли бы обрезать пробелы, сравнивая поля с заданным значением.
Проблема:-
Эластичная БД имеет поле "customField1" ="Jinesh ", и я передаю значение в search ="Jinesh", который не сравнивается и не дает никакого результата.
Что я ищу:-
Он должен искать точное заданное значение поиска, игнорируя пробелы в значениях упругого поля.
Любая помощь приветствуется.
Благодарю.
2 ответа
Есть несколько способов решить вашу проблему в зависимости от ваших требований. На мой взгляд, лучше всего подходит ваше описание. Regexp
запрос:
var result =
await
client.SearchAsync<object>(
searchDescriptor =>
searchDescriptor.Query(
queryDescriptor =>
queryDescriptor.Regexp(
regex => regex.OnField("customField1").Value(" *Jinesh *"))));
Другие варианты будут использовать Prefix
, Wildcard
или же MatchPhrasePrefix
,
Однако это идет вразрез с лучшими практиками Elasticsearch.
"Elasticsearch way" для этого будет анализировать свойство с помощью анализатора, который удаляет пробельные символы (это означает, что он будет сохранен в базе данных без пробелов). Пара анализаторов, которые делают это standard
анализатор (анализатор по умолчанию) или whitespace
анализатор. Вы также можете добавить собственный анализатор и использовать Trim Token Filter
с вашим токенизатором.
Вы можете сделать это, настроив свой индекс.
Если вам требуется конкретный анализатор, который не позволяет использовать какое-либо усечение пробелов, Elasticsearch предлагает добавить в свой индекс свойство, которое является просто копией рассматриваемого свойства (т. Е."CustomField1"), что может затем используйте более подходящий анализатор для этого сценария.
По умолчанию string
недвижимость на вашем POCO будет проиндексирована как проанализированная string
поле в 2.x, или как анализируемый text
поле в 5.x с not_analyzed keyword
подполе. Анализатор в обеих версиях - это стандартный анализатор, который, помимо прочего, разделяет входной поток символов на пробельные символы и удаляет их при генерации токенов.
Вы можете увидеть влияние анализатора на заданный строковый ввод с помощью Analyze API. В смысле/ консоли
GET _analyze
{
"text": ["Jinesh "],
"analyzer": "standard"
}
возвращается
{
"tokens": [
{
"token": "jinesh",
"start_offset": 0,
"end_offset": 6,
"type": "<ALPHANUM>",
"position": 0
}
]
}
Это токены, которые будут храниться в инвертированном индексе и вести поиск по ним.
Чтобы затем найти соответствие для этого с NEST, вы можете использовать match
запрос
void Main()
{
var pool = new SingleNodeConnectionPool(new Uri("http://localhost:9200"));
var defaultIndex = "default-index";
var connectionSettings = new ConnectionSettings(pool)
.DefaultIndex(defaultIndex);
var client = new ElasticClient(connectionSettings);
client.CreateIndex(defaultIndex, c => c
.Mappings(m => m
.Map<Person>(mm => mm
.AutoMap()
)
)
);
client.Index(new Person
{
Name = "Jinesh "
}, i => i.Refresh(Refresh.WaitFor));
var searchResponse = client.Search<Person>(s => s
.Query(q => q
.Match(m => m
.Field(f => f.Name)
.Query("Jinesh")
)
)
);
}
public class Person
{
public string Name { get; set; }
}
Ответ от поиска
{
"took" : 2,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"failed" : 0
},
"hits" : {
"total" : 1,
"max_score" : 0.2876821,
"hits" : [
{
"_index" : "default-index",
"_type" : "person",
"_id" : "AVjeLMxUCwxm5eXshs-y",
"_score" : 0.2876821,
"_source" : {
"name" : "Jinesh "
}
}
]
}
}