最近项目中使用到了ES,一切都开发好了,但是发现查询有问题。

由于在代码中用到了 wildcardQuery 而且还是用在时间上的,发现完全生效不了。只能一步步排查是什么原因

一、默认模板

由于 es 生成索引用的是用 logstash 来做的,logstash 有自己默认的模板,如果不配置自己的模板,就会以默认的模板来生成索引。

我们可以通过 http://127.0.0.1:9200/_template 链接来查看所有的模板。

也可以访问 http://127.0.0.1:9200/_template/logstash 来查看验证 logstash 的模板。

我们在 elasticsearch-head(具体如何安装可以自行百度) 里可以查看索引库信息,我们会发现,默认的模板会针对数据库的 timestamp 类型映射成 date 类型,是无法使用模糊查询的。

所以只能想办法该模板,或者改代码了。

二、改代码

由于 timestamp 映射成了 date 类型,无法模糊查询,当时试了好几次自定义模板都没成功,就想着改代码,曲线救国。

  1. logstash 配置文件里的sql 语句,针对要查询的日期字段生成了 对应的 yyyy-MMyyyy-MM-dd 格式的字段
  2. 更改代码里针对不同场景采用针对不同日期字段的精准查询

虽然实现了想要的效果,但是针对于自定义模板不生效,还是不死心。所以又是一通折腾,居然成功了。

三、自定义模板

一通的折腾,嘿,自定义模板成功了。

  1. 删除已经上传到 eslogstash 模板 DELETE http://localhost:9200/_template/logstash
  2. 自定义模板 ga-mapper.json ,下面的模板是在 logstash 的基础上改的。这里配置的是动态模板
{
    "index_patterns": "*ga*",
    "order": 1,
    "settings": {
        "index": {
          "refresh_interval": "10s",
          "number_of_shards": 1,
          "number_of_replicas": 0
        }
    },
    "mappings": {
        "dynamic_templates": [
            {
                "message_field": {
                    "path_match": "message",
                    "mapping": {
                        "norms": false,
                        "type": "text"
                    },
                    "match_mapping_type": "string"
                }
            },
            {
                "string_fields": {
                    "mapping": {
                        "norms": false,
                        "type": "text",
                        "fields": {
                            "keyword": {
                                "ignore_above": 256,
                                "type": "keyword"
                            }
                        }
                    },
                    "match_mapping_type": "string",
                    "match": "*"
                }
            },
            {
                "date_fields": {
                    "mapping": {
                        "norms": false,
                        "type": "text",
                        "fields": {
                            "keyword": {
                                "ignore_above": 256,
                                "type": "keyword"
                            }
                        }
                    },
                    "match_mapping_type": "date",
                    "match": "*"
                }
            }
        ],
        "properties": {
            "@timestamp": {
                "type": "date"
            },
            "geoip": {
                "dynamic": true,
                "properties": {
                    "ip": {
                        "type": "ip"
                    },
                    "latitude": {
                        "type": "half_float"
                    },
                    "location": {
                        "type": "geo_point"
                    },
                    "longitude": {
                        "type": "half_float"
                    }
                }
            },
            "@version": {
                "type": "keyword"
            }
        }
    }
}

注意:
index_patterns 要跟 logstash 配置文件的 index 对应上
order 一定要大于0

  1. 修改 logstash 的配置文件,这里主要是修改配置文件里的 output
output {
  elasticsearch {
        #es的ip和端口
        hosts => ["http://127.0.0.1:9200"]
        #ES索引名称(自己定义的)
        index => "ga"
        #自定义模板文件
        template => "F:/environment/logstash-7.3.2/ga-mapper.json"
        #模板名称
        template_name => "ga"
        manage_template => true
        #如果模板跟默认的logstash名称一直,则覆盖
        template_overwrite => true
        #设置数据的id为数据库中的字段
        document_id => "%{id}"
    }
    stdout {
        codec => json_lines
    }
}

然后启动 logstash 即可

对应的代码已经放到了这里 https://github.com/rocketAccoon/logstash/tree/main

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐