Использование Nest SuggestCompletion, выдает исключение «не поле предложения завершения»

Я новичок в эластичном поиске, и я пытался использовать подсказку завершения эластичного поиска, используя Nest для автозаполнения свойства.

Вот мое сопоставление (как уже упоминалось здесь: ):

  var createResult = client.CreateIndex(indexName, index => index                
            .AddMapping<Contact>(tmd => tmd
                .Properties(props => props
                    .Completion(s =>
                        s.Name(p => p.CompanyName.Suffix("completion"))
                        .IndexAnalyzer("standard")
                        .SearchAnalyzer("standard")
                        .MaxInputLength(20)
                        .Payloads()
                        .PreservePositionIncrements()
                        .PreserveSeparators())                        
                )
            )
        );
var resultPerson = client.IndexMany(documents.OfType<Person>(), new SimpleBulkParameters { Refresh = true });
var resultCompany = client.IndexMany(documents.OfType<Company>(), new SimpleBulkParameters { Refresh = true });

И во время индексации я просто использую метод IndexMany и передаю IEnumberable<Contact> (у контакта есть свойство по имени CompanyName, контакт является абстрактным классом, и Person, и Company являются его конкретными реализациями). Поиск выдает исключение с сообщением ElasticSearchException[Field [companyName] не является полем для предложения завершения]. И запрос выглядит следующим образом:

SearchDescriptor<Contact> descriptor = new SearchDescriptor<Contact>();
descriptor = descriptor.SuggestCompletion("suggest", c => c.OnField(f => f.CompanyName).Text(q));

var result = getElasticClientInstance("contacts").Search<Contact>(body => descriptor);

string qe = result.ConnectionStatus.ToString();

Что я здесь делаю неправильно, я просмотрел тесты Nest на SuggestCompletion, но не очень помог, то есть тест показывает только то, как получать предложения, но не то, как устанавливать сопоставления индексов для SuggestCompletion.

Я также попытался настроить токенизатор edgeNgram, как указано в этом опубликовать, но не смог продолжить и там.

Любое направление или пример того, как действовать, очень помогут.


person gsk    schedule 29.01.2014    source источник


Ответы (1)


ОБНОВЛЕНИЕ

Вы пытаетесь создать свойство с именем "companyName.completion", но в этой позиции оно недопустимо, и будет использоваться последний токен "completion". Таким образом, на самом деле это отображение поля, называемого завершением.... попробуйте изменить вызов на: .Name(p => p.CompanyName)

Другие замечания

Вы указываете сопоставление для Contact, но при индексировании используете типы Person и Company.

В терминах эластичного поиска вы сопоставили:

/index/contact/

но ваши документы идут в:

/index/person/ и /index/company

NEST не будет автоматически отображать все реализации определенного класса, и elasticsearch не может узнать, что эти три связаны.

Я бы реорганизовал отображение в метод и вызвал бы его для всех задействованных типов.

 var createResult = client.CreateIndex(indexName, index => index                
      .AddMapping<Contact>(tmd => MapContactCompletionFields(tmd))
      .AddMapping<Person>(tmd => MapContactCompletionFields(tmd))
      .AddMapping<Company>(tmd => MapContactCompletionFields(tmd))   
  );

 private RootObjectMappingDescriptor<TContact>  MapContactCompletionFields<TContact>(
      RootObjectMappingDescriptor<TContact> tmd)
      where TContact : Contact
 {
      return  tmd.Properties(props => props
           .Completion(s => s
                .Name(p => p.CompanyName.Suffix("completion"))
                .IndexAnalyzer("standard")
                .SearchAnalyzer("standard")
                .MaxInputLength(20)
                .Payloads()
                .PreservePositionIncrements()
                .PreserveSeparators()
           )                        
       );
 } 

Этот метод возвращает дескриптор, поэтому вы можете продолжить его цепочку.

Затем, когда вы выполняете поиск контактов:

var result = getElasticClientInstance("contacts").Search<Contact>(
    body => descriptor
        .Types(typeof(Person), typeof(Company))
);

Эта подсказка типов заставит поиск искать /index/person и /index/company и будет знать, как вернуть вам ковариантный список документов.

Таким образом, вы можете сделать result.Documents.OfType<Person>() после предыдущего вызова.

person Martijn Laarman    schedule 30.01.2014
comment
Спасибо за ответ. У меня по-прежнему возникает та же проблема: ElasticSearchException[Field [companyName] не является полем с предложением завершения]. Вот мой запрос: StatusCode: InternalServerError, Method: POST, Url: http://192.168.1.105:9200/contacts/people/_search, Request: { "suggest": { "suggest": { "text": "land", "completion": { "field": "companyName" } } } }. и я не уверен, как Person воспринимается как People, я не упоминаю об этом. То же самое для компании, она отображается как компании, а контакт как контакты. Можно ли использовать два «предложения» в запросе? - person gsk; 30.01.2014
comment
Можете ли вы вставить ответ для 192.168.1.105:9200/contacts/_mapping в свой ответ? или как суть на github? - person Martijn Laarman; 30.01.2014
comment
ааа, я понимаю, что происходит, вы пытаетесь создать свойство с именем companyName.completion, но в этой позиции оно недействительно, и оно будет использовать последнее завершение токена. Таким образом, на самом деле он отображает поле с именем completion.... попробуйте изменить вызов на: .Name(p => p.CompanyName) - person Martijn Laarman; 30.01.2014
comment
Вау, это помогло, спасибо. Теперь результат показывает общее количество попаданий для всех объектов. Должен ли он извлекать только те, у которых есть этот текст? И в выводе есть предложения, основанные на моем запросе, я не уверен, как вывести предложения, чтобы показать их пользователю, я предполагаю, что мне нужно запросить словарь предложений. gist.github.com/BharathChandra/8708544 - person gsk; 30.01.2014
comment
Да, NEST в настоящее время поддерживает предложения только для конечной точки _search, поэтому установите .Size(0) в дескрипторе поиска. Поддержка конечной точки _suggest находится в разработке!. Можете ли вы отметить ответ как принятый? - person Martijn Laarman; 30.01.2014
comment
@MartijnLaarman, ты можешь мне помочь? Я застрял в подобной ситуации здесь! stackoverflow.com/questions/23717387/ - person pedrommuller; 20.05.2014