Nest SuggestCompletion用法,抛出'不是完成建议字段'例外

 Still丶某某_546 发布于 2023-01-30 16:12

我是弹性搜索的完全初学者,我一直在尝试使用elasticsearch的完成建议,使用Nest来自动完成属性.

这是我的映射(如下所述:):

  var createResult = client.CreateIndex(indexName, index => index                
            .AddMapping(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(), new SimpleBulkParameters { Refresh = true });
var resultCompany = client.IndexMany(documents.OfType(), new SimpleBulkParameters { Refresh = true });

索引时我只是使用IndexMany方法并传递IEnumberable(Contact有一个名称为CompanyName的属性,Contact是一个抽象类,Person和Company都是它的具体实现).搜索引发异常,说ElasticSearchException [Field [companyName]不是完成建议字段].查询如下所示:

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

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

string qe = result.ConnectionStatus.ToString();

我在这里做错了什么,我查看了Nest的测试,SuggestCompletion但没有多少帮助,这意味着测试只描述了如何获得建议而不是如何设置SuggestCompletion的索引映射.

我也试过设置edgeNgram这篇文章中提到的标记器,但是也不能在那里继续.

关于如何进行的任何方向或示例将极大地帮助.

1 个回答
  • UPDATE

    您尝试创建名为"companyName.completion"的属性,但在该位置它无效,它将使用最后一个标记"completion".所以它实际上映射了一个名为completion的字段....尝试将调用更改为:.Name(p => p.CompanyName)

    其他观察

    您可以指定映射,Contact但在索引时使用PersonCompany类型.

    在elasticsearch术语中,您映射:

    /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>()在上次通话后做.

    2023-01-30 16:14 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有