如何实现elasticsearch suggester?

a11xaf1n  于 2021-06-14  发布在  ElasticSearch
关注(0)|答案(3)|浏览(346)

我正在尝试实现一个示例代码,它使用ElasticSearch的建议特性。
索引文档由一个平面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; }
}

Map如下

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/\u search?键入的\u keys=true。servererror:type:search\u phase\u execution\u exception reason:“all shards failed”causedby:“type:illegal\u argument\u exception reason:“找不到字段[suggest]的Map”causedby:“type:illegal\u argument\u exception reason:“找不到字段[suggest]的Map”
使用kibana查看我的索引Map:

"suggest": {
      "properties": {
        "input": {
          "type": "text",
          "fields": {
            "keyword": {
              "type": "keyword",
              "ignore_above": 256
            }
          }
        }
      }
    }

顺便说一下,我在.NETCore3.1中使用的是最新版本的nest(7.9.0)
我会感激你的帮助。

h6my8fg2

h6my8fg21#

看起来在发出create index with mapping请求时,candidates index和suggest字段可能已经存在。你可以查一下 CreateIndexResponse 回来看看是不是这样;这个 IsValid 属性将为false,响应上的错误详细信息将提供原因。
elasticsearch的默认行为将创建一个索引和Map,如果一个索引请求将一个文档索引到其中,则根据它看到的第一个文档推断字段的Map。对于许多用例来说,这是一种有用的行为,但是对于搜索用例,您通常希望在执行操作时使用显式Map来控制索引的创建,因此要关闭此行为,您可以设置 action.auto_create_index 群集设置为 false .. 现在,如果删除索引并使用createindex请求重新创建它,则在有机会显式创建它之前,不会自动创建它。

jm2pwxwz

jm2pwxwz2#

你是对的,Map定义是在索引一个文档时创建的,而不是根据我描述的Map定义创建的。检查createindexresponse isvalid属性表明出现了预期的问题。
我花了一些时间来找出根本问题:我使用的是es docker映像版本6.3.0和nest client 7。*使我的es与nest client兼容解决了这个问题。
谢谢你的帮助。

svgewumm

svgewumm3#

通过显式Map解决了同样的问题:

_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; }
}

相关问题