Elasticsearch中的不区分大小写的字段

时间:2015-10-03 04:06:26

标签: elasticsearch nest

我正在使用NEST和ElasticSearch,我尝试通过允许用户在搜索框中键入搜索短语来进行搜索。除了用户输入他们需要的搜索短语以确保字段名称与弹性搜索中的字段名称相同的情况之外,一切正常。

例如,我的一个字段名为bookTitle。如果他们搜索如下,那么它可以正常工作

bookTitle:"两个城市的故事"

如果他们像下面的例子那样搜索它不起作用

书签:"双城记" BookTitle:"两个城市的故事"

我用来搜索的代码如下。有没有人对如何解决这个问题有任何想法。我希望有一个ElasticSearch / NEST设置允许我这样做,而不是用搜索文本做一些丑陋的事情,比如找" BookTitle"并替换为" bookTitle"。

   public List<ElasticSearchRecord> Search(string searchterm) {

        var results = _client.Search<ElasticSearchRecord>(s => s
                        .Query(q => q
                            .QueryString(qs => qs
                                .DefaultField("content")
                                .Query(searchterm)
                            )
                        ));


        return results.Documents.ToList();
    }

非常感谢任何帮助。

3 个答案:

答案 0 :(得分:3)

使用Elasticsearch无法实现此目的。您可以控制映射,定义字段的名称,您就是控制查询的人。

根据此判断,您需要关注用户在搜索字段中输入的内容,开箱即用的Elasticsearch无法帮助您使用小写字段名称或类似内容。

因此,无论您选择哪种解决方案,都将是一种解决方法。

我的建议是定义一组规则,这些规则也应该传达给您的用户。围绕这些方面的东西:

  • 您的字段名称均为小写,或camel-cased
  • 您将映射定义为strict,以便您完全控制它
  • 您通知用户(在网络界面或用户界面中)他们应该在给定一组规则的情况下搜索字段名称(仅限小写,或仅限驼峰等)

另一种方法是定义what goes into the _all field。在您的QueryString中,您不使用特定的字段名称,ES将使用query_string的默认设置。这意味着ES将使用_all_all字段,您知道它包含的内容。

仅仅是为了提及,但无论如何我不建议,我认为你可以使用script做任何事情你想要Groovy中的字段名称。但是,这意味着你不会使用Elasticsearch的真正力量

如上所述,教育您的用户并定义一组要遵守的规则。

答案 1 :(得分:2)

您可以在C#内存中缓存映射,并确认从中找到所有搜索字段。如果未找到完全匹配,则尝试找到最佳匹配字段。如果有多个选项可供选择,则抛出错误并要求用户更具体。

实际上,用户界面可以在输入时动态执行此操作,并帮助他们选择正确的选项。

答案 2 :(得分:0)

Haven未将其作为生产质量进行测试,但从理论上讲,您可以使用小写命名策略保存所有对象,并使用.ToLower()查询字段,以便它们始终匹配。

首先创建适当的命名策略:

public class LowercaseNamingStrategy : Newtonsoft.Json.Serialization.NamingStrategy
{
    protected override string ResolvePropertyName(string name)
    {
        return name.ToLower();
    }
}

适当的序列化器:

    public class ElasticSerializer : JsonNetSerializer
    {
        public ElasticSerializer(IConnectionSettingsValues settings)
            : base(settings)
        {
            this.ContractResolver.NamingStrategy = new LowercaseNamingStrategy();
        }
    }

然后在NEST客户端的连接设置中使用序列化程序:

        var pool = new StaticConnectionPool([your nodes]);
        var settings = new ConnectionSettings(pool, s => new ElasticSerializer(s));
        var client = new ElasticClient(settings);

这会将您的字段存储为小写。然后在查询时,只需强制所有用户提供的字段为小写,并且事物应该排成一行。

如果您不是从头开始,则必须重新填充数据以保持命名策略的统一。