ElasticSearch Kibana

2021-08-03  本文已影响0人  54番茄

Download Elasticsearch官网下载地址

一、下载elasticsearch-7.12.0,上传到linux服务器,解压。

//进入es配置文件夹,修改基础配置:
$ cd  elasticsearch-7.12.0/config/ 
$ vim elasticsearch.yml 

修改elasticsearch.yml配置:
1.集群名称:一个运行elasticsearch 实例称为一个节点,而集群是由一个或者多个拥有相同 cluster.name 配置的节点组成, 它们共同承担数据和负载的压力。当有节点加入集群中或者从集群中移除节点时,集群将会重新平均分布所有的数据

cluster.name: fanqie-es

2.设置节点名称:当一个节点被选举成为 主 节点时, 它将负责管理集群范围内的所有变更,例如增加、删除索引,或者增加、删除节点等。 而主节点并不需要涉及到文档级别的变更和搜索等操作,所以当集群只拥有一个主节点的情况下,即使流量的增加它也不会成为瓶颈。 任何节点都可以成为主节点。我们的示例集群就只有一个节点,所以它同时也成为了主节点

node.name: node-1

注意:如果若存在多个主(master)节点,需要要设置cluster.initial_master_nodes参数,详见官网 重要参数配置,若设置不当会发生脑裂,集群就会处在丢失数据的危险中。

3、数据文件夹设置(可选)

默认情况下,Elasticsearch 会把插件、日志以及你最重要的数据放在安装目录下。这会带来不幸的事故, 如果你重新安装 Elasticsearch 的时候不小心把安装目录覆盖了。如果你不小心,你就可能把你的全部数据删掉了。
最好的选择就是把你的数据目录配置到安装目录以外的地方, 同样你也可以选择转移你的插件和日志目录,当然你也选择不修改。
更改如下:

#/path/to/data2  是安装目录路径 可以设定到其他地方
path.data: /path/to/data1,/path/to/data2 
# Path to log files:
path.logs: /path/to/logs
4、集群引导设置(cluster.initial_master_nodes参数官网说明)
旧版elasticssearch的(遗弃)
- discovery.zen.minimum_master_nodes

Elasticsearch7新增参数,写入候选主节点的节点名称,cluster.initial_master_nodes替换上面的配置
- cluster.initial_master_nodes=[master-node-a,master-node-b,master-node-c]

   当你第一次启动一个全新的 Elasticsearch集群时,有一个集群引导步骤,它决定了在第一次选举中投票的主合格节点集。在开发模式下,发现是没有配置的,这一步由节点自己自动执行。由于这种自动引导本质上是不安全的,当您在生产模式下启动一个全新的集群时,您必须明确列出在第一次选举中应计算其选票的主合格节点。该列表是使用设置来 cluster.initial_master_nodes设置的。

5、发现和集群形成设置(discovery.seed_hosts)
此设置为老版本设置,旧名称已被弃用,但继续工作以保持向后兼容性,在未来的版本中将删除对旧名称的支持。(遗弃)
- discovery.zen.ping.unicast.hosts

Elasticsearch7新增参数,写入候选主节点的设备地址,来开启服务时就可以被选为主节点
- discovery.seed_hosts: ["127.0.0.1:9300","127.0.0.1:9301"]

在进入生产环境之前,应该配置两个重要的发现和集群形成设置,以便集群中的节点可以相互发现并选举主节点,他们之间的本质区别:
cluster.initial_master_nodes:仅在集群首次启动会使用。
discovery.seed_hosts:每次启动都需要。

5、节点主从以及节点功能设置

    在生产环境下,如果不修改elasticsearch节点的角色信息,在高数据量,高并发的场景下集群容易出现脑裂等问题(一种两个主节点同时存在于一个集群的现象)。
默认情况下,elasticsearch集群中每个节点都有成为主节点的资格,也都存储数据,还可以提供查询服务。这些功能是由两个属性控制:node.masternode.data:

默认情况下这两个属性的值都是true。下面详细介绍一下这两个属性的含义以及不同组合可以达到的效果。

  • node.master
    这个属性表示节点是否具有成为主节点的资格
    注意:此属性的值为true,并不意味着这个节点就是主节点。因为真正的主节点,是由多个具有主节点资格的节点进行选举产生的。所以,这个属性只是代表这个节点是不是具有主节点选举资格。
  • node.data
    这个属性表示节点是否存储数据。

2、四种属性组合
这两个属性可以有四种组合:
(1)这种组合表示这个节点即有成为主节点的资格,又存储数据。这个时候如果某个节点被选举成为了真正的主节点,那么他还要存储数据,这样对于这个节点的压力就比较大了。elasticsearch默认每个节点都是这样的配置,在测试环境下这样做没问题。实际工作中建议不要这样设置,这样相当于主节点和数据节点的角色混合到一块了。

node.master: true
node.data: true

(2)这种组合表示这个节点没有成为主节点的资格,也就不参与选举,只会存储数据。这个节点我们称为data(数据)节点。在集群中需要单独设置几个这样的节点负责存储数据,后期提供存储和查询服务。

node.master: false
node.data: true'

(3)这种组合表示这个节点不会存储数据,有成为主节点的资格,可以参与选举,有可能成为真正的主节点。这个节点我们称为master节点。

node.master: true
node.data: false

(4)这种组合表示这个节点即不会成为主节点,也不会存储数据,这个节点的意义是作为一个client(客户端)节点,主要是针对海量请求的时候可以进行负载均衡。

node.master: false
node.data: false

默认情况下,每个节点都有成为主节点的资格,也会存储数据,还会处理客户端的请求。在一个生产集群中我们可以对这些节点的职责进行划分。

建议:
(1)集群中设置3台以上的节点作为master节点【node.master: true node.data: false】。这些节点只负责成为主节点,维护整个集群的状态。
(2)再根据数据量设置一批data节点【node.master: false node.data: true】。这些节点只负责存储数据。
(3)后期提供建立索引和查询索引的服务,如果用户请求比较频繁,这些节点的压力也会比较大。所以在集群中建议再设置一批client节点【node.master: false node.data: false】。这些节点只负责处理用户请求,实现请求转发,负载均衡等功能。
(4)配置。
master节点:普通服务器即可(CPU 内存 消耗一般);
data节点:主要消耗磁盘,内存;
client节点:普通服务器即可(如果要进行分组聚合操作的话,建议这个节点内存也分配多一点)。

二、启动es

ES 是不能使用 root 用户来启动,必须创建一个普通用户来安装启动,否则会报错。

#添加普通用户esuser
$ useradd esuser
#可以查看所有的用户的列表
$ cat /etc/passwd
#授权esuser用户对es的最大操作权限
$ chown -R esuser:esuser   elasticsearch-7.12.0
#切换到esuser普通用户下
$ su - esuser

后台启动,并输出启动日志到nohup日志文件(nohup自己随便写都行):

./elasticsearch  > nohup &

ok,上面就可以完成一个单机单节点的elasticsearch服务后台启动了。

如果想实现elasticsearch集群,可以在同一目录下复制一下elasticsearch-7.12.0已经配置好的目录就好可以了(服务器资源有限):

#在当前目录下,复制一份elasticsearch-7.12.0
$ cp -r elasticsearch-7.12.0 elasticsearch-7.12.0-two

遇到错误一:单机多节点配置,可能出现的错误:

java.lang.IllegalStateException: failed to obtain node locks, tried [[/usr/local/es_path/data]] with lock id [0]; maybe these locations are not writable or multiple nodes were started without increasing [node.max_local_storage_nodes] (was [1])?

报错原因:
后台已经存在运行elasticsearch的进程。node.max_local_storage_nodes这个配置限制了单节点上可以开启的ES存储实例的个数,我们需要开多个实例,因此需要把这个配置写到配置文件中,根据同一台服务器上部署的节点个数,为这个配置赋值为2或者更高,。

遇到错误二:单机双主节点,在初始化的时候报错,两个竞争master后启动的一直报错:

 [node-2] master not discovered yet, this node has not previously joined a bootstrapped (v7+) cluster, and this node must discover master-eligible nodes [node-1, node-2] to bootstrap a cluster: have discovered [{node-2}{tW7GbJF1Qi6zAilVvNKLvw}{mFRhAlJQTx2RUmLvyfAzkQ}{10.100.4.10}{10.100.4.10:9301}{cdfhilmrstw}{ml.machine_memory=8203501568, xpack.installed=true, transform.node=true, ml.max_open_jobs=20, ml.max_jvm_size=1073741824}]; discovery will continue using [10.100.4.10:9200, 10.100.4.10:9201] from hosts providers and [{node-2}{tW7GbJF1Qi6zAilVvNKLvw}{mFRhAlJQTx2RUmLvyfAzkQ}{10.100.4.10}{10.100.4.10:9301}{cdfhilmrstw}{ml.machine_memory=8203501568, xpack.installed=true, transform.node=true, ml.max_open_jobs=20, ml.max_jvm_size=1073741824}] from last-known cluster state; node term 0, last-accepted version 0 in term 0
{"type": "server", "timestamp": "2021-08-03T08:29:13,536+08:00", "level": "WARN", "component": "o.e.c.NodeConnectionsService", "cluster.name": "stamp-es", "node.name": "node-2", "message": "failed to connect to {node-1}{b4nENEqfQzSP9B0LHWZsHg}{J-qzfhihTCii-IHDCklIEg}{10.100.4.10}{10.100.4.10:9300}{cdfhilmrstw}{ml.machine_memory=8203501568, ml.max_open_jobs=20, xpack.installed=true, ml.max_jvm_size=1073741824, transform.node=true} (tried [4921] times)", "cluster.uuid": "-WWW-aT8ThylLVHhEWqDQQ", "node.id": "tW7GbJF1Qi6zAilVvNKLvw" , 
"stacktrace": ["org.elasticsearch.transport.ConnectTransportException: [node-1][10.100.4.10:9300] connect_exception",
"at org.elasticsearch.transport.TcpTransport$ChannelsConnectedListener.onFailure(TcpTransport.java:968) ~[elasticsearch-7.12.0.jar:7.12.0]",
"at org.elasticsearch.action.ActionListener.lambda$toBiConsumer$2(ActionListener.java:202) ~[elasticsearch-7.12.0.jar:7.12.0]",
"at org.elasticsearch.common.concurrent.CompletableContext.lambda$addListener$0(CompletableContext.java:31) ~[elasticsearch-core-7.12.0.jar:7.12.0]",
"at java.util.concurrent.CompletableFuture.uniWhenComplete(CompletableFuture.java:859) ~[?:?]",
"at java.util.concurrent.CompletableFuture$UniWhenComplete.tryFire(CompletableFuture.java:837) ~[?:?]",
"at java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:506) ~[?:?]",
"at java.util.concurrent.CompletableFuture.completeExceptionally(CompletableFuture.java:2152) ~[?:?]",
"at org.elasticsearch.common.concurrent.CompletableContext.completeExceptionally(CompletableContext.java:46) ~[elasticsearch-core-7.12.0.jar:7.12.0]",
"at org.elasticsearch.transport.netty4.Netty4TcpChannel.lambda$addListener$0(Netty4TcpChannel.java:57) ~[?:?]",
"at io.netty.util.concurrent.DefaultPromise.notifyListener0(DefaultPromise.java:577) ~[?:?]",
"at io.netty.util.concurrent.DefaultPromise.notifyListeners0(DefaultPromise.java:570) ~[?:?]",
"at io.netty.util.concurrent.DefaultPromise.notifyListenersNow(DefaultPromise.java:549) ~[?:?]",
"at io.netty.util.concurrent.DefaultPromise.notifyListeners(DefaultPromise.java:490) ~[?:?]",
"at io.netty.util.concurrent.DefaultPromise.setValue0(DefaultPromise.java:615) ~[?:?]",
"at io.netty.util.concurrent.DefaultPromise.setFailure0(DefaultPromise.java:608) ~[?:?]",
"at io.netty.util.concurrent.DefaultPromise.tryFailure(DefaultPromise.java:117) ~[?:?]",
"at io.netty.channel.nio.AbstractNioChannel$AbstractNioUnsafe.fulfillConnectPromise(AbstractNioChannel.java:321) ~[?:?]",
"at io.netty.channel.nio.AbstractNioChannel$AbstractNioUnsafe.finishConnect(AbstractNioChannel.java:337) ~[?:?]",
"at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:702) ~[?:?]",
"at io.netty.channel.nio.NioEventLoop.processSelectedKeysPlain(NioEventLoop.java:615) ~[?:?]",
"at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:578) ~[?:?]",
"at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:493) ~[?:?]",
"at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:989) ~[?:?]",
"at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) ~[?:?]",
"at java.lang.Thread.run(Thread.java:832) [?:?]",
"Caused by: io.netty.channel.AbstractChannel$AnnotatedConnectException: 拒绝连接: 10.100.4.10/10.100.4.10:9300",
"Caused by: java.net.ConnectException: 拒绝连接",
"at sun.nio.ch.Net.pollConnect(Native Method) ~[?:?]",
"at sun.nio.ch.Net.pollConnectNow(Net.java:660) ~[?:?]",
"at sun.nio.ch.SocketChannelImpl.finishConnect(SocketChannelImpl.java:875) ~[?:?]",
"at io.netty.channel.socket.nio.NioSocketChannel.doFinishConnect(NioSocketChannel.java:330) ~[?:?]",
"at io.netty.channel.nio.AbstractNioChannel$AbstractNioUnsafe.finishConnect(AbstractNioChannel.java:334) ~[?:?]",

解决方式:
开始我设置discovery.seed_hosts: ["10.100.4.10:9200","10.100.4.10:9201"]端口是外部访问端口,一直形成不了集群,后来详细看了下启动日志,elasticsearch设置节点间交互的tcp端口,默认是9300,然后修改为discovery.seed_hosts: ["10.100.4.10:9300","10.100.4.10:9301"],完美启动了,构成集群。如果要自定义内部节点之间沟通端口,使用这个transport.tcp.port:设置就好了。

完整的elasticsearch .xml配置如下:

#跨域配置
http.cors.enabled: true
http.cors.allow-origin: "*"
#节点1的配置信息:
#集群名称
cluster.name: elasticsearch
#节点名称
node.name: node-1
#是不是有资格竞选主节点
node.master: true
#是否存储数据
node.data: true
#最大集群节点数
node.max_local_storage_nodes: 3
#端口
http.port: 9201
#内部节点之间沟通端口
transport.tcp.port: 9301
#es7.x 之后新增的配置,写入候选主节点的设备地址,在开启服务后可以被选为主节点
discovery.seed_hosts: ["10.100.4.10:9300","10.100.4.10:9301"]
#es7.x 之后新增的配置,初始化一个新的集群时需要此配置来选举master
cluster.initial_master_nodes: ["node-1", "node-1"]
#数据存储路径
path.data: /usr/local/es_path/logs
#日志存储路径
path.logs: /usr/local/es_path/logs

以上配置如果在多个节点使用,只需要修改端口设置以及节点名称就可以了,其他配置不用动,启动后这两个节点会竞争,其中一个成为主节点。

集群信息展示
上面使用Google的ElasticSearch Head插件,可以用于数据的浏览查询,节点状态观测,当然还有其他方式安装ElasticSearch Head,但是我比较懒,这个是最简单的方式。
ElasticSearch Head

集群健康值

集群健康值status 字段指示着当前集群在总体上是否工作正常,如上图(集群信息展示),正常状态为绿色。它的三种颜色含义如下:

status 健康描述
green 所有的主分片和副本分片都正常运行。
yellow 所有的主分片都正常运行,但不是所有的副本分片都正常运行。
red 有主分片没能正常运行。

上面提到的这些颜色的实际意义。集群的健康状况为yellow则表示全部主分片都正常运行(集群可以正常服务所有请求),但是副分片没有全部处在正常状态。 也就说如果有索引的3个副本分片都是unassigned ,表示它们都没有被分配到任何节点。 在同一个节点上既保存原始数据又保存副本是没有意义的,因为一旦失去了那个节点,我们也将丢失该节点上的所有副本数据。

通过Kibana可视化工具,监控集群的配置信息、状态信息

    Kibana是一个针对Elasticsearch的开源分析及可视化平台,用来搜索、查看交互存储在Elasticsearch索引中的数据。使用Kibana,可以通过各种图表进行高级数据分析及展示。它操作简单,基于浏览器的用户界面,实时显示Elasticsearch查询动态。设置Kibana非常简单,几分钟内就可以完成Kibana安装并启动 Elasticsearch索引监测,这个安装步骤就不详细介绍了,网上一大堆。
Download Kibana 官网下载地址
安装完成后,我们就可以使用开发工具,对现有的集群获取一些信息操作:

#查看集群状态
GET /_cluster/health
#查看集群是否健康
GET /_cat/health?v
#查看集群节点
GET /_cat/nodes

更多命令详见官网: 集群健康

节点统计(重点有用)
GET _nodes/stats
集群统计,官网没解释返回数据
GET _cluster/stats

节点是排列在nodes,以节点的 UUID 作为键名。还显示了节点网络属性的一些信息(比如传输层地址和主机名)。这些值对调试诸如节点未加入集群这类自动发现问题很有用。通常你会发现是端口用错了,或者节点绑定在错误的 IP 地址/网络接口上了。可以又处于解决遇到的错误二。

此命令可以返回线程池信息、jvm信息,Elasticsearch 被配置为当 heap 达到 75% 的时候开始 GC。如果你的节点一直 >= 75%,你的节点正处于 内存压力 状态。这是个危险信号,不远的未来可能就有慢 GC 要出现了。,字段详解见官网: GET _nodes/stats数据返回详解

#创建索引
PUT /my_index
{
   "settings" : {
      "number_of_shards" : 3,
      "number_of_replicas" : 1
   }
}
# | grep -v marvel  表示剔除 Marval 索引
GET /_cat/indices?bytes=b' | sort -rnk8 | grep -v marvel
#统计 my_index 索引
GET my_index/_stats 
#使用逗号分隔索引名可以请求多个索引统计值
GET my_index,another_index/_stats 
#使用特定的 _all 可以请求全部索引的统计值
GET _all/_stats 

索引可以辨别或验证集群中的热门索引,或者试图找出某些索引比其他索引更快或者更慢的原因。
实践中,节点为中心的统计还是显得更有用些。瓶颈往往是针对整个节点而言,而不是对于单个索引。因为索引一般是分布在多个节点上的,这导致以索引为中心的统计值通常不是很有用,因为它们是从不同环境的物理机器上汇聚的数据。索引为中心的统计作为一个有用的工具可以保留在你的技能表里,但是通常它不会是第一个用的上的工具。详解见官网: 索引统计

索引模板

    索引模板,简而言之,是一种复用机制,就像一些项目的开发框架一样,省去了大量的重复,体力劳动。当新建一个 elasticsearch索引时,自动匹配模板,完成索引的基础部分搭建。在开发中,elasticsearch很大一部分工作是用来处理日志信息的,比如某公司对于日志处理策略是以日期为名创建每天的日志索引。并且每天的索引映射类型和配置信息都是一样的,只是索引名称改变了。如果手动的创建每天的索引,将会是一件很麻烦的事情。为了解决类似问题,elasticsearch提供了预先定义的模板进行索引创建,这个模板称作为Index Templates。通过索引模板可以让类似的索引重用同一个模板。模板只在创建索引时应用。更改模板不会对现有索引产生影响,一部分定义的设置/映射将优先于模板中定义的任何匹配设置/映射。
这一段话可以简单理解类似于咱们需要对Mysql根据时间自动分库分表,每个月创建一个新表的过程。索引模板,就类似于create库时候每个字段的要定义什么类型。当然这仅仅是帮助你去理解什么是索引模板,索引模板并不仅仅只有这么简单的行为。在使用shardingsphere或者 Mycat,进行分库分表的时候,所用库表都需要提前创建的,这个就是我为什么研究elasticsearch原因,因为我不想每次提前就建表。

template for index-pattern
只有匹配 logstash-* 的索引才会应用这个模板。有时候我们会变更 Logstash 的默认索引名称,记住你也得通过 PUT 方法上传可以匹配你自定义索引名的模板。当然,我更建议的做法是,把你自定义的名字放在 "logstash-" 后面,变成 index => "logstash-custom-%{+yyyy.MM.dd}" 这样。

GET  _cat/templates/
GET _template                // 查看所有模板
GET _template/my_index*          // 查看与通配符相匹配的模板
GET _template/my_index1,my_index2    // 查看多个模板
GET _template/my_index  // 查看指定模板
DELETE _template/my_index
HEAD _template/my_index
PUT  _template/my_index
{
    "index_patterns": ["my_index*"],
    "settings": {
        "number_of_shards": 3,
        "number_of_replicas": 2
    },
    "mappings": {
        "properties": {
            "userId": {
                "type": "long"
            },
            "userName": {
                "type": "text"
            },
            "userDeptName": {
                "type": "text",
                "analyzer": "ik_smart"
            },
            "businessType": {
                "type": "keyword"
            },
            "actionTime": {
                "type": "date",
                "format": "yyyy-MM-dd HH:mm:ss"
            }
        }
    }
}

index_patterns:是索引模式,意思就是当以my_index开头的索引,都会匹配这个模板,如my_index_1,my_index_20210803
settings:设置主分片3,复制分片2
mappings:在这个指定存储数据的映射关系

创建 mapping 时,可以为字符串(专指type : keyword) 指定ignore_above ,用来限定字符长度。超过 ignore_above 的字符会被存储,但不会被索引。注意,是字符长度,一个英文字母是一个字符,一个汉字也是一个字符。在动态生成的 mapping 中,keyword类型会被设置ignore_above: 256ignore_above可以在创建 mapping时指定。不为关键词的时候,analyzer可以设定中文或者一段文件,被切分的程度:ik_smartik_max_word。其中 ik_smart为最少切分,k_max_word : 细粒度分词,会穷尽一个语句中所有分词可能。

PUT _commodity/_settings
{
    "number_of_replicas": 3
}

测试一下

简单创建一个索引并插入数据,不使用模板,ES会自己决定的映射规则:

创建了一个索引为testindex,type为testtype,id为1数据
PUT /testindex/testtype/1
{
    "first_name" : "张三",
    "last_name" :  "法外狂徒张三",
    "age" :        25,
    "about" :      "我是个好人"
}
只创建了索引不插入数据
PUT /testindex2
{
}
es默认先创建了索引,然后插入数据
数据插入成功

索引模板差异比对参考

Elasticsearch 时间存储后展示问题

    毕竟是初次使用Elasticsearch,这个时间问题,把我坑的不轻,毕竟还是关系型数据库思维,我想存入索引的时间数据是格式化后的数据,但是一直存的是时间戳,曾一度怀疑是版本的问题,后来看见一个帖子才明白,是入参json的问题,java定义的Date类型,不能直接json转化后传入,不然你在索引模板中设置任何date格式都没用:
如我在上面设置的date格式,设置索引中的actionTime:

"actionTime": {
                "type": "date",
                "format": "yyyy-MM-dd HH:mm:ss"
            }

开发工具输入参数

POST /my_index/_doc/2
{
   "actionTime": "2018-07-29 08:00:00"
}
正确演示,数据格式化展示

相应的我们在代码中需要加入以下对时间的注解:


使用JSONField注解,别使用@JsonFormat 它只会在类似@ResponseBody返回json数据的时候,才会返回格式化的yyyy-MM-dd HH:mm:ss时间,
你直接使用System.out.println()输出的话,仍然是类似“Fri Dec 01 21:05:20 CST 2021”这样的时间样式
这个时间会差八个小时,所以别用new Date() 获取时间,使用下面提供的getCurrentDate方式


import com.alibaba.fastjson.annotation.JSONField;
@JSONField(format="yyyy-MM-dd HH:mm:ss")
private Date actionTime;

public static Date getCurrentDate() {
        LocalDateTime datetime = LocalDateTime.now(ZoneId.of("Asia/Shanghai"));
        ZonedDateTime zdt = datetime.atZone(ZoneId.systemDefault());
        return Date.from(zdt.toInstant());
    }

谨记:索引模板配置的时间格式一个要与传入的时间格式一致,否则就会报错。

PUT my_index/_doc/1
{
  "actionTime": 1543151405000
}

这样如果传入一个时间戳格式,会报错时间解析失败:

Caused by: ElasticsearchException[Elasticsearch exception [type=date_time_parse_exception, reason=date_time_parse_exception: Text '1627988093053' could not be parsed at index 0]]
at org.elasticsearch.ElasticsearchException.innerFromXContent(ElasticsearchException.java:485)
at org.elasticsearch.ElasticsearchException.fromXContent(ElasticsearchException.java:396)
at org.elasticsearch.ElasticsearchException.innerFromXContent(ElasticsearchException.java:426)
... 76 more
如果确实需要传入的是个时间戳,不设定format参数类型就OK了:

"actionTime": {
                "type": "date"
            }

格式化成功了但是实际上这个字段是Text类型,单纯的用于展示没问题,用来做搜索条件或者间隔查询基本无效。

Dynamic templates说明
Dynamic mapping这种方式下字段的映射规则基本都是ES自己决定的,它可以解决一部分场景,但有时候ES并不能很好的理解我们的业务数据,这就需要我们像上面写的自己指定属性。给个样式,混个脸熟,反正我是不这样玩。

{
    "order": 0,
    "version": 60001,
    "index_patterns": [
        "my_index*"
    ],
    "settings": {
        "index": {
            "number_of_shards": "5",
            "number_of_replicas": 2,
            "refresh_interval": "5s"
        }
    },
    "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": "*"
                }
            }
        ],

    "aliases": {}
}

参考:
https://www.cnblogs.com/Neeo/articles/10869231.html
https://www.jianshu.com/p/1f67e4436c37
https://www.cnblogs.com/caoweixiong/p/11791438.html

上一篇下一篇

猜你喜欢

热点阅读