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)

相关推荐

  • servletservice方法的参数(如何将service注入到servlet)

    技术servlet.service()方法怎么调用这篇文章主要介绍“servlet.service()方法怎么调用”,在日常操作中,相信很多人在servlet.service()方法怎么调用问题上存在疑惑,小编查阅了各式

    攻略 2021年12月24日
  • 为什么企业出海需要选择美国服务器

    技术为什么企业出海需要选择美国服务器由于现在租用海外建站的用户有不少,主流的主要有香港服务器、美国服务器、台湾服务器等,在这篇文章中,我将讨论什么是租用美国服务器以及您为什么需要它。什么是租用美国服务器? 租用美国服务器

    礼包 2021年12月8日
  • 百万级MySQL的数据量怎么快速完成数据迁移

    技术百万级MySQL的数据量怎么快速完成数据迁移这篇文章主要讲解了“百万级MySQL的数据量怎么快速完成数据迁移”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“百万级MyS

    攻略 2021年11月18日
  • 姓田有涵养的男孩名字,男孩帅气有涵养的名字姓王氏

    技术姓田有涵养的男孩名字,男孩帅气有涵养的名字姓王氏帅气有涵养的王氏名字:王嘉佰姓田有涵养的男孩名字、王杰宁、王钦宁、王伦昌、王子嘉、王皓诚、王哲雨、王建宝、王俊南、王博尘、王佰星、王逸林、王钦睿、王棋嘉、王子睿、王尚翔

    生活 2021年10月24日
  • php如何强行转数组

    技术php如何强行转数组这篇文章主要介绍php如何强行转数组,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完! php强行转数组的方法:1、新建一个php文件,并将一个字符

    攻略 2021年11月30日
  • 椭圆机面板按键图说明,三鼎全站仪键盘按钮说明

    技术椭圆机面板按键图说明,三鼎全站仪键盘按钮说明面板上按键功能——进入坐标测量模式键椭圆机面板按键图说明。
    ◢——进入距离测量模式键。
    ANG——进入角度测量模式键。
    MENU——进入主菜单测量模式键。
    ESC——用于中

    生活 2021年10月22日