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)

相关推荐

  • html5是什么缩写(html5缩写成h5)

    技术html5是什么的缩写这篇文章给大家分享的是有关html5是什么的缩写的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。 html5是HyperText Marku

    攻略 2021年12月13日
  • vuex的几种方法和作用(vuex学习目标是什么教程)

    技术vuex的核心概念和基本使用是怎么样的vuex的核心概念和基本使用是怎么样的,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。介绍Vuex是实现组件全局状态

    攻略 2021年12月15日
  • 风的笔顺是,风的第二笔的笔画名称是什么

    技术风的笔顺是,风的第二笔的笔画名称是什么撇、横折弯钩/横斜钩、撇、点风的笔顺是。 风字详解: 一、详细信息:
    拼音:fēng、fěng  
    部首:风
    笔画:4
    二、笔顺图: 三、基本释义:
    (1)读作:fēn

    生活 2021年10月25日
  • C++中为什么gsl::joining_thread好于std::thread

    技术C++中为什么gsl::joining_thread好于std::thread本篇内容主要讲解“C++中为什么gsl::joining_thread好于std::thread”,感兴趣的朋友不妨来看看。本文介绍的方法

    攻略 2021年11月25日
  • 速度单位换算,物理长度、速度单位换算

    技术速度单位换算,物理长度、速度单位换算常用单位常用的长度单位有速度单位换算:公里{千米} (km)、分米(dm)、厘米(cm)、毫米(mm)、微米(μm)、纳米(nm)、皮米(pm)、飞米(fm)。
    (1)公里
    公里又

    生活 2021年10月30日
  • Python怎么实现装饰器

    技术Python怎么实现装饰器小编给大家分享一下Python怎么实现装饰器,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!普通装饰器:直接上代码

    攻略 2021年11月2日