#c# #asp.net-core #elasticsearch #nest
#c# #asp.net-core #elasticsearch #гнездо
Вопрос:
Я пытаюсь реализовать пример кода, который использует функцию предложения из Elastic Search.
Индексированный документ состоит из плоского POCO
public class CandidateDocument
{
public Guid Id { get; set; }
public string Name { get; set; }
public string FirstName { get; set; }
public DateTime BirthDate { get; set; }
public CompletionField Suggest { get; set; }
}
Отображение выглядит следующим образом
var client = new ElasticClient(settings);
client.Indices.Create("candidates", c =>
c.Map<CandidateDocument>(m =>
m.Properties(ps => ps.Text(s => s.Name(n => n.Name)
.Store(false)
.Fields(f => f.Keyword(k => k.Name("nameRaw"))))
.Text(s => s.Name(n => n.FirstName)
.Store(false)
.Fields(f => f.Keyword(k => k.Name("firstNameRaw"))
.Date(s => s.Name(n => n.BirthDate).Format("ddMMyyyy"))
.Keyword(s => s.Name(n => n.Id))))
.Completion(c => c.Name(n => n.Suggest)))));
Индексирование документа выглядит следующим образом:
var candidateDocument = new CandidateDocument
{
Id = Guid.NewGuid(),
Name = "Lennon",
FirstName = "John",
BirthDate = DateTime.Now,
Suggest = new CompletionField
{
Input = new[] { "Lennon" },
}
};
var indexResponse = await this.elasticClient.IndexAsync(candidateDocument, i => i.Index("candidates"));
И мой запрос :
var searchResponse = await this.elasticClient.SearchAsync<CandidateDocument>(s => s.Index("candidates").Suggest(su => su
.Completion("suggestions", c => c
.Field(f => f.Suggest)
.Prefix(query)
.Fuzzy(f => f.Fuzziness(Fuzziness.Auto))
.Size(5))));
Я столкнулся с проблемой, связанной со следующей проблемой :
Исключение Elasticsearch.Net.ElasticsearchClientException: запрос не удалось выполнить. Вызов: Код статуса 400 из: POST /candidates/_search?typed_keys=true. Ошибка сервера: Тип: search_fase_execution_exception Причина: «сбой всех сегментов» Вызвано by: «Тип: illegal_argument_exception Причина: «не найдено сопоставление для поля [предложить]» Вызвано by: «Тип: illegal_argument_exception Причина: «не найдено сопоставление для поля [предложить]»
Глядя на мое отображение индекса с использованием kibana :
"suggest": {
"properties": {
"input": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
}
Кстати, я использую последнюю версию Nest (7.9.0) в .NET Core 3.1
Я был бы признателен за вашу помощь.
Ответ №1:
Была такая же проблема, решаемая явными сопоставлениями :
_elasticClient.Indices.Create("candidates", c => c
.Map<CandidateDocument>(m => m
.Properties(ps => ps
.Completion(s => s
.Name(n => n.Suggest)))));
public class CandidateDocument
{
public Guid? Id { get; set; }
public CompletionField Suggest { get; set; }
}
Ответ №2:
Похоже, что индекс кандидатов и поле предложения, возможно, уже существовали на момент выдачи запроса на создание индекса с сопоставлением. Вы могли бы проверить CreateIndexResponse
возвращенное значение, чтобы убедиться, что это так; IsValid
свойство будет false, а в ответе будут указаны сведения об ошибке, объясняющие, почему.
Поведение Elasticsearch по умолчанию создаст индекс и сопоставление, если поступит запрос на индексацию документа в нем, выводя сопоставление для полей на основе первого документа, который он видит. Это полезное поведение для многих вариантов использования, но для вариантов использования поиска обычно требуется контролировать создание индексов с явными сопоставлениями, как вы это делаете, поэтому, чтобы отключить это поведение, вы можете установить для action.auto_create_index
параметра кластера значение false
.. Теперь, если вы удалите индекс и воссоздадите его снова с помощью вашего запроса на создание индекса, он не будет автоматически создан до того, как у вас появится возможность явно создать его.
Ответ №3:
Вы правы, определение сопоставления было создано при индексировании документа, не созданного на основе описанного мной определения сопоставления. Проверка свойства CreateIndexResponse isValid указывает, как вы и ожидали, на проблему.
Мне потребовалось время, чтобы разобраться с основной проблемой: я использовал образ ES Docker версии 6.3.0 и клиент Nest 7. * Совместимость моего ES с моим клиентом Nest устранила проблему.
Спасибо за вашу помощь.