Elasticsearch Nest查询以在比较具有提供值的字段时修剪空格

时间:2016-12-08 06:59:49

标签: c# elasticsearch nest

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

问题: -

弹性数据库有字段“customField1”=“Jinesh”,我将值传递给search =“Jinesh”,它没有比较并且没有提供任何结果。

我在寻找:

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

非常感谢任何帮助。

感谢。

2 个答案:

答案 0 :(得分:1)

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

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

其他选项将使用PrefixWildcardMatchPhrasePrefix

但是,这违反了Elasticsearch最佳做法。

这样做的“弹性搜索方式”是使用剥离空白字符的分析器来分析属性(意味着它将保存在没有空格的数据库中)。这样做的几个分析仪是standard分析仪(默认分析仪)或whitespace分析仪。您还可以添加自定义分析器,并将Trim Token Filter与您的标记器一起使用。

您可以configuring your index完成此操作。

如果您需要一个不允许使用任何空格修剪的特定分析器,Elasticsearch建议您在索引中添加一个属性,该属性只是相关属性的副本(即“customField1”) ,然后可以在这种情况下使用更好的适合分析器。

答案 1 :(得分:1)

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

您可以使用 Analyze API 查看分析器对给定字符串输入的影响。在Sense / Console

GET _analyze
{
  "text": ["Jinesh          "],
  "analyzer": "standard"
}

返回

{
  "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          "
        }
      }
    ]
  }
}