【问题标题】:Elastic Search multi match弹性搜索多重匹配
【发布时间】:2019-06-04 08:05:34
【问题描述】:

我是 ElasticSearch 的新手。现在我有一个要求,需要返回包含关键字的所有结果。

public Class People(){
    public string UserId {get; set;}
    public string FirstName {get; set;}
    public string LastName {get; set;}
}

如果三个字段之一包含关键字,我想过滤所有人物,类似于 like "%keyword%"

例如,我有一个人

var people = new People() {
    UserId = "lastname.middlename.firstname",
    FirstName = "firstname",
    LastName = "lastname"
}

我如何通过搜索关键字ddl得到这个人,如何设置索引以及如何查询。

我尝试使用 NEST 进行如下查询

  var keyword = "ddl"
  var result = await _client.SearchAsync<People>(s => 
      s.Query(q => q.MultiMatch(m => m.Fields(f => f.Field(ff => ff.UserId).Field(ff => ff.FirstName).Field(ff => ff.LastName)).Query(keyword)))
  );

这行不通。仅当我将关键字更改为 firstnamelastnamelastname.middlename.firstname

时才有效

有什么方法可以满足要求吗?

【问题讨论】:

    标签: elasticsearch nest


    【解决方案1】:

    简短的回答是,您需要为每个目标字段配置一个分析器,将术语标记为三元组,可能使用 ngram token filter 并将 min_grammax_gram 设置为 3。此分析将生成一个ddlmiddlename 的令牌将匹配您的查询。

    更长的答案是,您需要了解Analysis,以及如何使用.NET 客户端writetest analyzers。您可能想通过the example repository that builds a Nuget search application。这是一个相当复杂的演练,涉及许多概念,包括分析。

    【讨论】:

    • 是否有任何查询方法只返回匹配的原始术语,而不是同义词或其他内容?
    【解决方案2】:

    要搜索部分字段,您应该在映射中使用ngram tokenizer

    它将使用不同大小的窗口标记您的字段。

    这应该可以解决您的问题,但您需要注意几点:

    • 您可能只想在索引时使用此分析器。在索引和搜索中使用此标记器可能会生成 LOT 不相关的结果。
    • 使用最小窗口大小(min_gram 参数)不要太小。在您的情况下,3 将起作用。
    • 索引的大小可以大幅增长。

    另一种实现更简单但通常效率不高的解决方案是在查询字符串中使用wildcards queries。它与 SQL 中的 LIKE 运算符非常相似。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-10
      • 1970-01-01
      相关资源
      最近更新 更多