Elasticsearch 嵌套查询 trim 空格,同时将字段与提供的值进行比较

Elasticsearch Nest query to trim white spaces while comparing fields with provided value

我正在使用 Nest API 进行弹性搜索,我正在寻找一些解决方案,我们可以在比较字段与提供的值时使用 trim 空格。

问题:-

Elastic DB 有字段 "customField1" ="Jinesh          ",我正在将值传递给搜索 ="Jinesh",它不比较也不提供任何结果。

我要找的是:-

它应该通过忽略弹性字段值中的空格来搜索准确提供的搜索值。

如有任何帮助,我们将不胜感激。

谢谢。

根据您的要求,有多种方法可以解决您的问题。在我看来,最符合您的描述的是使用 Regexp 查询:

var result =
            await
                client.SearchAsync<object>(
                    searchDescriptor =>
                        searchDescriptor.Query(
                            queryDescriptor =>
                                queryDescriptor.Regexp(
                                    regex => regex.OnField("customField1").Value(" *Jinesh *"))));

其他选项将使用 PrefixWildcardMatchPhrasePrefix

但是,这违背了 Elasticsearch 的最佳实践。

这样做的 "Elasticsearch way" 是使用去除空白字符的分析器来分析 属性(这意味着它将在没有空白的情况下保存在数据库中)。 standard 分析器(默认分析器)或 whitespace 分析器是执行此操作的几个分析器。您还可以添加自定义分析器并将 Trim Token Filter 与您的分词器一起使用。

您可以通过 configuring your index 完成。

如果您需要一个不允许您使用任何空白修剪的特定分析器,Elasticsearch 建议您在索引中添加一个 属性,它只是 [=35] 的一个副本=] 有问题(即 "customField1"),然后可以针对这种情况使用更适合的分析器。

默认情况下,POCO 上的 string 属性 将被索引为 2.x 中已分析的 string 字段,或作为已分析的 text 5.x 中带有 not_analyzed keyword 子字段的字段。两个版本中的分析器都是 Standard Analyzer,除此之外,它在空白字符上拆分输入字符流,并在生成标记时将其删除。

您可以使用 Analyze API. In Sense/Console

查看分析器对给定字符串输入的影响
GET _analyze
{
  "text": ["Jinesh          "],
  "analyzer": "standard"
}

returns

{
  "tokens": [
    {
      "token": "jinesh",
      "start_offset": 0,
      "end_offset": 6,
      "type": "<ALPHANUM>",
      "position": 0
    }
  ]
}

这些是将存储在倒排索引中并用于搜索的标记。

然后使用 NEST 找到匹配项,您可以使用 match query

void Main()
{
    var pool = new SingleNodeConnectionPool(new Uri("http://localhost:9200"));
    var defaultIndex = "default-index";
    var connectionSettings = new ConnectionSettings(pool)
            .DefaultIndex(defaultIndex);

    var client = new ElasticClient(connectionSettings);

    client.CreateIndex(defaultIndex, c => c
        .Mappings(m => m
            .Map<Person>(mm => mm
                .AutoMap()
            )
        )
    );

    client.Index(new Person
    {   
        Name = "Jinesh          "
    }, i => i.Refresh(Refresh.WaitFor));

    var searchResponse = client.Search<Person>(s => s
        .Query(q => q
            .Match(m => m
                .Field(f => f.Name)
                .Query("Jinesh")
            )
        )
    );
}

public class Person
{
    public string Name { get; set; }
}

搜索结果为

{
  "took" : 2,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "failed" : 0
  },
  "hits" : {
    "total" : 1,
    "max_score" : 0.2876821,
    "hits" : [
      {
        "_index" : "default-index",
        "_type" : "person",
        "_id" : "AVjeLMxUCwxm5eXshs-y",
        "_score" : 0.2876821,
        "_source" : {
          "name" : "Jinesh          "
        }
      }
    ]
  }
}