ES 添加字段默认值

技术ES 添加字段默认值 ES 添加字段默认值ES 新增字段支持过滤
业务背景
当我们在使用多维度检索时,mysql显然已经不能满足我的的使用场景,尤其涉及到表之间的join且数据量较大时,mysql的

添加专家系统字段默认值

ES 新增字段支持过滤

业务背景

当我们使用多维检索时,mysql显然不能满足我的使用场景,尤其是涉及到表与表之间的连接,数据量大的时候,mysql的查询性能就捉襟见肘了。

这时,ES的多维检索功能就派上用场了。我们可以将两个或两个以上的业务表做成一个更宽的索引,监控业务的binlog,并将数据保存到es中。

这样可以快速支持业务检索。

业务需求

通常会用到ES的动态模板,以后添加其他维度过滤会更方便。

大家都知道文档存储在ES的底层。当使用POST将字段添加到动态模板中时,先前的数据将不会具有与mysql相同的默认值。

如果产品端需要支持旧数据的过滤,那么我们就要参与刷ES索引。

分析

按照数据组织的方式,将数据重新插入到ES中肯定是不可行的。那么我们有没有一个可以类似于mysql的设置默认值的命令呢?

所以我翻了翻ES的官方文档,看到更新可以支持这个操作。下面是一个在es动态索引中添加类型的示例,以演示解决过程。若要实现,请在es中添加类型=0的原始文档,并支持索引。

现有文档数

GET index _ test/_ count Pitty

{

计数' : 2000,

_碎片' : {

共计: 12,

成功' : 12,

跳过' : 0,

失败' : 0

}

}

你可以看到另外2000份文件,

使用ES的term查询:

实际上,“术语”是一个桶聚合查询,可以理解为mysql的group by。

POST _ index _ test/_ search Pitty

{

尺寸' : 0,

aggs' : {

aggType' : {

条款' : {

字段“:”类型

}

}

}

}

查询结果:

{

拍了' : 2,

' time out _ : false,

_碎片' : {

共计: 12,

成功' : 12,

跳过' : 0,

失败' : 0

},

点击量' : {

总计' : {

值' : 2000,

关系' : 'gte '

},

max_score' : null,

点击量' : [ ]

},

聚合' : {

aggType' : {

doc _ count _ error _ upper _ bound ' : 0,

sum_other_doc_count' : 0,

桶' : [

{

密钥' : 1,

doc_count' : 5

},

{

key' : 2,

doc_count' : 4

},

{

key' : 3,

doc_count' : 4

}

]

}

}

}

可以看到,没有type=0的数据,只有新生成的type=1、2、3、2、3的数据,分别是5、4、4,共13条,数据总条数为2000条。

有1987件物品不见了。这些数据都是旧数据,不支持该字段的检索。

使用update更新

POST索引_test/_update/1

{

脚本' : {

lang': '无痛',

来源' : '

if (ctx。_source.type==null) { ctx。_source.type=0 }

'''

}

}

ES update支持脚本,这样我们在加载更新文档的时候,就可以根据其他一个或者几个字段来确认新添加的字段的值,我这里用的就是这个。

如果type为空,则将type指定为默认值0。

更新后使用术语查询结果。

` `` json

{

拍了' : 2,

time out _ : false,

_碎片' : {

共计: 12,

成功f

ul" : 12,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 2000,
"relation" : "gte"
},
"max_score" : null,
"hits" : [ ]
},
"aggregations" : {
"aggType" : {
"doc_count_error_upper_bound" : 0,
"sum_other_doc_count" : 0,
"buckets" : [
{
"key" : 0,
"doc_count" : 1
}
{
"key" : 1,
"doc_count" : 5
},
{
"key" : 2,
"doc_count" : 4
},
{
"key" : 3,
"doc_count" : 4
}
]
}
}
}

发现只增加了一条,重复执行更新命令也不会再增加了,通过分析update语句发现,其命令行update后的1指的是doc
Id。这种方式显然不能使用,我再猜想有没有类似mysql中根据条件update的语句呀查看官方文档后,返现ES支持
update_by_query的操作

使用update_by_query

使用update_by_query语句,在这里我删除了script中的条件判断,改成使用query

POST index_test/_update_by_query
{
    "script": {
        "lang": "painless",
        "source": "ctx._source.type=0"
    },
    "query": {
        "bool": {
            "must_not": {
                "exists": {
                    "field": "type"
                }
            }
        }
    }
}

其实使用scrpit的脚本判断要比query中使用must_not要慢。我理解使用script要access all 全表扫描。
如果使用了must_not 而且只有一个条件,我理解ES的执行引擎会使用倒排所以,查询出有的,然后取反,把不存在该字段的
doc ID返回。根据id去逐条更新,这样判断的次数从O(n)降到了理论的O(1)。

待结果返回后,重新使用term查询结果:

POST index_test/_searchpretty
{
    "size" : 0,
    "aggs" : {
        "aggType" : {
            "terms" : {
                "field" : "type"
            }
        }
    }
}

查询结果:

{
  "took" : 2,
  "timed_out" : false,
  "_shards" : {
    "total" : 12,
    "successful" : 12,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 2000,
      "relation" : "gte"
    },
    "max_score" : null,
    "hits" : [ ]
  },
  "aggregations" : {
    "aggType" : {
      "doc_count_error_upper_bound" : 0,
      "sum_other_doc_count" : 0,
      "buckets" : [
          {
          "key" : 0,
          "doc_count" : 1987
        }
        {
          "key" : 1,
          "doc_count" : 5
        },
        {
          "key" : 2,
          "doc_count" : 4
        },
        {
          "key" : 3,
          "doc_count" : 4
        }
      ]
    }
  }
}

可以看到聚合结果中key=0的文档相较之前增加了好多,而且key = 0,1,2,3,4 的枚举加起来正好为2000.
证明更新成功了。

控制更新速度

在更新的过程中,如果要控制更新的速度,可以在更新的语句后添加参数,目前ES更新支持两个方式

按照索引分片更新

POST index_test/_update_by_queryrouting=1

其中routing为集群的第几个分片。

  • 优点:单分片更新,如果分片被更新坏了,可以找运维删除分片,副本分片会主动替换主分片,并重新
    分片副本分片,在这期间索引的状态可能是黄色。
  • 缺点:更新不是原子的,而且需要清楚集群有多少个主分片才可以操作。

按照分页更新

POST index_test/_update_by_queryscroll_size=10000

其中scroll_size的最大值为集群配置的允许的最大值,可以通过_settings命令查询。

  • 优点:可以控制集群中数据的更新速度,降低修复数据时,集群的负载。
  • 缺点:需要判断使用合理的分页,一旦集群崩溃就会影响线上环境。

触类旁通

ES集群使用的SSD的硬盘,而且对内存要求较高,
当集群的存储超过一半时(超过了一半ES就无法再实现段合并了,高并发写入会产生较多分段Segment)
。一半情况下,业务的数据都是按照日期存储的,这时候我们可以把较早的数据备份到HDFS系统上,然后
在ES的集群上执行delete_by_query可以删除部分历史数据,这样可以使得ES集群一直处于比较好的性能区间。

I am chris, not arax!

内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/112083.html

(0)

相关推荐

  • 为什么要使用数据库连接池及其好处是什么

    技术为什么要使用数据库连接池及其好处是什么为什么要使用数据库连接池及其好处是什么,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。对于一个简单的

    攻略 2021年12月2日
  • Jmeter(二十九)

    技术Jmeter(二十九) Jmeter(二十九) - 从入门到精通 - Jmeter Http协议录制脚本工具-Badboy2(详解教程)-------------------------------

    礼包 2021年12月1日
  • pagerank算法原理举例子(pagerank算法详解)

    技术PageRank算法如何给网页排名PageRank算法如何给网页排名,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。1,PageRank 算法原理Page

    攻略 2021年12月23日
  • 简易学生管理系统

    技术简易学生管理系统 简易学生管理系统此系统可实现学生信息的添加、删除、修改和查看。
    运行效果如下所示:实现代码如下所示:1 package heima;2 3 public class Student

    礼包 2021年11月15日
  • php7.2运行失败怎么解决

    技术php7.2运行失败怎么解决本篇内容主要讲解“php7.2运行失败怎么解决”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“php7.2运行失败怎么解决”吧!

    攻略 2021年12月9日
  • 如何修改IIS目录的ASP.NET版本

    技术如何修改IIS目录的ASP.NET版本这篇文章将为大家详细讲解有关如何修改IIS目录的ASP.NET版本,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。一个用于修改虚拟目录的ASP.

    攻略 2021年11月19日