Elasticsearch Map对not_analyzed文档不敏感

时间:2014-06-04 11:54:06

标签: elasticsearch

我有一个带有以下映射的类型

PUT /testindex
{
    "mappings" : {
        "products" : {
            "properties" : {
                "category_name" : {
                    "type" : "string",
                    "index" : "not_analyzed" 
                }
            }
        }
    }

}

我想搜索一个确切的单词。这就是为什么我将其设置为not_analyzed。 但问题是我想用小写或大写搜索[不区分大小写]。

我搜索了它,并找到了一种设置不区分大小写的方法。

curl -XPOST localhost:9200/testindex -d '{
  "mappings" : {
    "products" : {
      "properties" : {        
        "category_name":{"type": "string", "index": "analyzed", "analyzer":"lowercase_keyword"}
      }
    }
  }
}'

有没有办法将这两个映射到同一个字段。?

谢谢..

8 个答案:

答案 0 :(得分:38)

我认为这个例子符合您的需求:

$ curl -XPUT localhost:9200/testindex/ -d '
{
  "settings":{
     "index":{
        "analysis":{
           "analyzer":{
              "analyzer_keyword":{
                 "tokenizer":"keyword",
                 "filter":"lowercase"
              }
           }
        }
     }
  },
  "mappings":{
     "test":{
        "properties":{
           "title":{
              "analyzer":"analyzer_keyword",
              "type":"string"
           }
        }
     }
  }
}'

取自此处:How to setup a tokenizer in elasticsearch

它在字符串字段上使用关键字tokenizer和小写过滤器,我相信它可以做你想要的。

答案 1 :(得分:6)

如果您只想要不区分大小写的查询,请考虑在开展业务之前将数据和查询更改为大写/小写。

这意味着您保留字段not_analyzed并仅在其中一个案例中输入数据/查询。

答案 2 :(得分:4)

我相信这个要点最能回答你的问题:  * https://gist.github.com/mtyaka/2006966

您可以在映射期间多次索引字段,并且我们一直执行此操作,其中一个是not_analyzed而另一个是。我们通常将not_analyzed版本设置为.raw

就像John P.写的那样,您可以在运行时设置分析器,或者您可以在服务器启动时在配置中设置一个,如上面的链接:

# Register the custom 'lowercase_keyword' analyzer. It doesn't do anything else
# other than changing everything to lower case.
index.analysis.analyzer.lowercase_keyword.type: custom
index.analysis.analyzer.lowercase_keyword.tokenizer: keyword
index.analysis.analyzer.lowercase_keyword.filter: [lowercase]

然后使用not_analyzed版本和分析版本定义您的字段的映射:

# Map the 'tags' property to two fields: one that isn't analyzed,
# and one that is analyzed with the 'lowercase_keyword' analyzer.
curl -XPUT 'http://localhost:9200/myindex/images/_mapping' -d '{
  "images": {
    "properties": {
      "tags": {
        "type": "multi_field",
        "fields": {
          "tags": {
            "index": "not_analyzed",
            "type": "string"
          },
          "lowercased": {
            "index": "analyzed",
            "analyzer": "lowercase_keyword",
            "type": "string"
          }
        }
      }
    }
  }
}'

最后你的查询(在构建查询之前注意小写值以帮助找到匹配):

# Issue queries against the index. The search query must be manually lowercased.
curl -XPOST 'http://localhost:9200/myindex/images/_search?pretty=true' -d '{
  "query": {
    "terms": {
      "tags.lowercased": [
        "event:battle at the boardwalk"
      ]
    }
  },
  "facets": {
    "tags": {
      "terms": {
        "field": "tags",
        "size": "500",
        "regex": "^team:.*"
      }
    }
  }
}'

答案 3 :(得分:3)

只需使用keyword令牌化程序和lowercase令牌过滤器创建自定义分析器。

答案 4 :(得分:3)

在这种情况下,我建议您将lowercase filterkeyword tokenizer合并到自定义分析器中。并小写您的搜索输入关键字。

1.使用分析器结合小写过滤器和关键字标记器

创建索引
curl -XPUT localhost:9200/test/ -d '
{
  "settings":{
     "index":{
        "analysis":{
           "analyzer":{
              "your_custom_analyzer":{
                 "tokenizer":"keyword",
                 "filter": ["lowercase"]
              }
           }
        }
    }
}'

2.Put mappings并使用analyzer

设置字段属性
curl -XPUT localhost:9200/test/_mappings/twitter -d '
{
    "twitter": {
        "properties": {
            "content": {"type": "string", "analyzer": "your_custom_analyzer" }
        }
    }
}'

3.您可以在通配符查询中搜索您想要的内容。

curl -XPOST localhost:9200/test/twitter/ -d '{

    "query": {
        "wildcard": {"content": "**the words you want to search**"}
    }  
}'

以不同方式搜索字段的另一种方式。我对U的建议是使用multi_fields类型。

您可以在multi_field

中设置字段
curl -XPUT localhost:9200/test/_mapping/twitter -d '
{
    "properties": {
        "content": {
            "type": "multi_field",
            "fields": {
                "default": {"type": "string"},
                "search": {"type": "string", "analyzer": "your_custom_analyzer"}
            }
        }
    }
}'

因此,您可以使用上面的映射属性索引数据。最后以两种方式搜索它(默认/ your_custom_analyzer)

答案 5 :(得分:1)

我们可以使用ElasticSearch脚本对非分析字符串进行不区分大小写的搜索。

使用内联脚本进行示例查询:

{
    "query" : {
        "bool" : {

            "must" : [{
                    "query_string" : {
                        "query" : "\"apache\"",
                        "default_field" : "COLLECTOR_NAME"
                    }
                }, {
                    "script" : {
                        "script" : "if(doc['verb'].value != null) {doc['verb'].value.equalsIgnoreCase(\"geT\")}"
                    }
                }
            ]

        }
    }
}

您需要在elasticsearch.yml文件中enable scripting。在搜索查询中使用脚本可能会降低整体搜索性能。如果您希望脚本执行得更好,那么您应该使用java插件使它们“原生”。

示例插件代码:

public class MyNativeScriptPlugin extends Plugin {

    @Override
    public String name() {
        return "Indexer scripting Plugin";
    }


    public void onModule(ScriptModule scriptModule) {
        scriptModule.registerScript("my_script", MyNativeScriptFactory.class);

    }

    public static class MyNativeScriptFactory implements NativeScriptFactory {

        @Override
        public ExecutableScript newScript(@Nullable Map<String, Object> params) {
            return new MyNativeScript(params);
        }

        @Override
        public boolean needsScores() {
            return false;
        }
    }

    public static class MyNativeScript extends AbstractSearchScript {
        Map<String, Object> params;

        MyNativeScript(Map<String, Object> params) {
            this.params = params;
        }

        @Override
        public Object run() {
            ScriptDocValues<?> docValue = (ScriptDocValues<?>) doc().get(params.get("key"));
            if (docValue instanceof Strings) {
                return ((String) params.get("value")).equalsIgnoreCase(((Strings) docValue).getValue());
            }
            return false;
        }
    }
}

使用本机脚本的示例查询:

{
    "query" : {
        "bool" : {

            "must" : [{
                    "query_string" : {
                        "query" : "\"apache\"",
                        "default_field" : "COLLECTOR_NAME"
                    }
                }, {
                    "script" : {
                        "script" : "my_script",
                        "lang" : "native",
                        "params" : {
                            "key" : "verb",
                            "value" : "GET"
                        }
                    }
                }
            ]

        }
    }
}

答案 6 :(得分:1)

它很简单,只需创建如下映射

{
    "mappings" : {
        "products" : {
            "properties" : {
                "category_name" : {
                    "type" : "string" 
                }
            }
        }
    }

}

如果您希望使用不区分大小写,则无需提供索引,因为默认索引将是&#34;标准&#34;这将照顾不区分大小写。

答案 7 :(得分:-1)

我希望我能添加评论,但我不能。所以这个问题的答案是“这是不可能的”。

  

分析器由单个Tokenizer和零个或多个TokenFilters组成。

我希望我能告诉你一些事情,但花4个小时研究,就是答案。我处于同样的境地。您无法跳过标记化。它全部开启或全部关闭。