【问题标题】:Change default mapping of string to "not analyzed" in Elasticsearch在 Elasticsearch 中将字符串的默认映射更改为“未分析”
【发布时间】:2016-11-01 18:54:02
【问题描述】:

在我的系统中,数据的插入总是通过 csv 文件通过 logstash 完成。我从不预先定义映射。但是每当我输入一个字符串时,它总是被认为是analyzed,因此像hello I am Sinha这样的条目被拆分为helloIamSinha。无论如何我可以更改弹性搜索的默认/动态映射,以便所有字符串,无论索引,无论类型如何都被视为not analyzed?或者有没有办法在.conf 文件中设置它?说我的conf 文件看起来像

input {  
      file {
          path => "/home/sagnik/work/logstash-1.4.2/bin/promosms_dec15.csv"
          type => "promosms_dec15"
          start_position => "beginning"
          sincedb_path => "/dev/null"
      }
}
filter {

    csv {
        columns => ["Comm_Plan","Queue_Booking","Order_Reference","Multi_Ordertype"]
        separator => ","
    }  
    ruby {
          code => "event['Generation_Date'] = Date.parse(event['Generation_Date']);"
    }

}
output {  
    elasticsearch { 
        action => "index"
        host => "localhost"
        index => "promosms-%{+dd.MM.YYYY}"
        workers => 1
    }
}

我希望所有字符串都是not analyzed,而且我也不介意它是所有未来数据插入到 elasticsearch 中的默认设置

【问题讨论】:

    标签: elasticsearch logstash logstash-grok elasticsearch-mapping


    【解决方案1】:

    只需创建一个模板。运行

    curl -XPUT localhost:9200/_template/template_1 -d '{
        "template": "*",
        "settings": {
            "index.refresh_interval": "5s"
        },
        "mappings": {
            "_default_": {
                "_all": {
                    "enabled": true
                },
                "dynamic_templates": [
                    {
                        "string_fields": {
                            "match": "*",
                            "match_mapping_type": "string",
                            "mapping": {
                                "index": "not_analyzed",
                                "omit_norms": true,
                                "type": "string"
                            }
                        }
                    }
                ],
                "properties": {
                    "@version": {
                        "type": "string",
                        "index": "not_analyzed"
                    },
                    "geoip": {
                        "type": "object",
                        "dynamic": true,
                        "path": "full",
                        "properties": {
                            "location": {
                                "type": "geo_point"
                            }
                        }
                    }
                }
            }
        }
    }'
    

    【讨论】:

    • 这个做了什么?它是如何工作的?您能否详细说明一下这个模板是什么以及它如何应用于这个问题?
    • @Brad 如您在此处看到的,在dynamic templatesproperties 内部,index 设置为not analyzed。结果,如果我们输入一个字符串hello, I am Sinha,它将被视为一个字符串,而不是拆分成helloIamSinha
    • 此映射适用的索引名称是什么?
    • 它适用于所有索引@AbtPst
    • 好的,这是有道理的。如果我只想应用于索引的某些字段怎么办?假设我有一个索引ind。传入数据中的字段数不固定,但肯定会有一个字符串 fieldd。我只想分析字段d,不分析所有其他字符串字段。
    【解决方案2】:

    您可以查询您的字段的.raw 版本。这是在Logstash 1.3.1 中添加的:

    我们提供的 logstash 索引模板会为您索引的每个字段添加一个“.raw”字段。这些“.raw”字段由 logstash 设置为“not_analyzed”,因此不会进行分析或标记化——我们的原始值按原样使用!

    因此,如果您的字段名为 foo,您将查询 foo.raw 以返回 not_analyzed(不按分隔符拆分)版本。

    【讨论】:

    • foo.raw 字段为空,而 foo 字段已填充。没看懂
    • @Roland Kofler 你发现他们为什么是空的了吗?我有同样的问题
    • @AviArro 我只记得它是这样设计的。有点像黑客。更多我不记得了
    • 有这个问题的每个人都会使用logstash吗?
    • @JonCrowell 是的,不是的。前几天我不使用logstash时偶然发现了我的答案。我无法摆脱.raw 字段并意识到这是logstash 为我创建的东西,所以我在这里的回答没有帮助。 :) 但是,这个问题被标记并指的是logstash,所以我的答案是被接受的答案是有道理的。还有其他有关使用 vanilla Elasticsearch 创建 not_analyzed 字段的相关 SO 问题和答案可供参考。
    【解决方案3】:

    从您的 Logstash 发行版(可能安装为 /opt/logstash/lib/logstash/outputs/elasticsearch/elasticsearch-template.json)复制 lib/logstash/outputs/elasticsearch/elasticsearch-template.json,修改通过替换

    "dynamic_templates" : [ {
      "string_fields" : {
        "match" : "*",
        "match_mapping_type" : "string",
        "mapping" : {
          "type" : "string", "index" : "analyzed", "omit_norms" : true,
          "fields" : {
            "raw" : {"type": "string", "index" : "not_analyzed", "ignore_above" : 256}
          }
        }
      }
    } ],
    

    "dynamic_templates" : [ {
      "string_fields" : {
        "match" : "*",
        "match_mapping_type" : "string",
        "mapping" : {
          "type" : "string", "index" : "not_analyzed", "omit_norms" : true
        }
      }
    } ],
    

    并指向template,将插件输出到修改后的文件:

    output {
      elasticsearch {
        ...
        template => "/path/to/my-elasticsearch-template.json"
      }
    }
    

    您仍然可以为特定字段覆盖此默认值。

    【讨论】:

    • 这似乎没有给我想要的结果...我有一个名为 State 的字段,其中有一个名为 West Bengal 的实例。当我绘制条形图时,我得到 2 个不同的图例,即 westbengal,这是错误的。问题依旧
    • 这是在新索引中吗?请记住,更改索引模板不会对现有数据产生影响。
    • 我删除了以前的索引,刷新了它,然后再次插入。是的,它在一个新索引中
    • 有趣。如果您get the mapping of the index 并查看正在使用的实际映射怎么办?
    • 它显示{"promosms-16.12.2014":{"mappings":{"promosms_dec15":{"properties":{..............,"State":{"type":"string"},.........}}}}}没有关于它是否被分析的信息
    【解决方案4】:

    我认为更新映射只是为了报告目的而处理字段的错误方法。迟早您可能希望能够在该字段中搜索令牌。如果您将字段更新为“not_analyzed”并希望从值“foo bar”中搜索 foo,您将无法执行此操作。

    更优雅的解决方案是使用 kibana 聚合过滤器而不是术语。类似下面的内容将搜索词 ivr04 和 ivr02。所以在你的情况下,你可以有一个过滤器“你好,我是辛哈”。希望这会有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-05-13
      • 1970-01-01
      • 2013-11-15
      • 1970-01-01
      • 2023-04-11
      • 2014-11-27
      • 2016-11-05
      • 1970-01-01
      相关资源
      最近更新 更多