python - 使用 Python 批量更新 elasticsearch 文档
问题描述
我有如下弹性搜索文档,我需要根据creationtime currentdate纠正年龄值
年龄 = 创建时间 - 当前日期
:
hits = [
{
"_id":"CrRvuvcC_uqfwo-WSwLi",
"creationtime":"2018-05-20T20:57:02",
"currentdate":"2021-02-05 00:00:00",
"age":"60 months"
},
{
"_id":"CrRvuvcC_uqfwo-WSwLi",
"creationtime":"2013-07-20T20:57:02",
"currentdate":"2021-02-05 00:00:00",
"age":"60 months"
},
{
"_id":"CrRvuvcC_uqfwo-WSwLi",
"creationtime":"2014-08-20T20:57:02",
"currentdate":"2021-02-05 00:00:00",
"age":"60 months"
},
{
"_id":"CrRvuvcC_uqfwo-WSwLi",
"creationtime":"2015-09-20T20:57:02",
"currentdate":"2021-02-05 00:00:00",
"age":"60 months"
}
]
我想根据每个文档 ID 进行批量更新,但问题是我需要更正 6 个月的数据和每个数据大小(索引的文档计数)几乎是535329,我想有效地根据_id对年龄进行批量更新每天使用 python 处理所有文档。
有没有办法做到这一点,而无需循环,我遇到的所有使用 Pandas 数据帧进行更新的示例都是基于已知值。但是在这里_id我会在代码运行时得到。
我编写的逻辑是获取所有文档并存储它们的_id,然后为每个_id更新年龄。但如果我想在 6 个月的每一天批量更新所有文档,这不是一种有效的方法。
谁能给我一些想法或指出正确的方向。
解决方案
如评论中所述,无需获取 ID。您甚至不需要自己获取文件!
一个_update_by_query
电话就足够了。解析日期后,您可以使用它ChronoUnit
来获取差异:
POST your-index-name/_update_by_query
{
"query": {
"match_all": {}
},
"script": {
"source": """
def created = LocalDateTime.parse(ctx._source.creationtime, DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss"));
def currentdate = LocalDateTime.parse(ctx._source.currentdate, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
def months = ChronoUnit.MONTHS.between(created, currentdate);
ctx._source._age = months + ' month' + (months > 1 ? 's' : '');
""",
"lang": "painless"
}
}
尝试在文档的一小部分上运行此更新脚本,然后通过添加除match_all
我放在那里的查询之外的查询来释放整个索引。
值得一提的是,除非你在这个age
字段上进行搜索,否则它不需要存储在你的索引中,因为它可以在查询时计算出来。
你看,如果你的索引映射的日期是这样正确定义的:
{
"mappings": {
"properties": {
"creationtime": {
"type": "date",
"format": "yyyy-MM-dd'T'HH:mm:ss"
},
"currentdate": {
"type": "date",
"format": "yyyy-MM-dd HH:mm:ss"
},
...
}
}
}
age
可以计算为脚本字段:
POST ttimes/_search
{
"query": {
"match_all": {}
},
"script_fields": {
"age_calculated": {
"script": {
"source": """
def months = ChronoUnit.MONTHS.between(
doc['creationtime'].value,
doc['currentdate'].value );
return months + ' month' + (months > 1 ? 's' : '');
"""
}
}
}
}
唯一需要注意的是,该值不会在内部,_source
而是在其自己的调用组内部fields
(这意味着一次可能有更多脚本字段!)。
"hits" : [
{
...
"_id" : "FFfPuncBly0XYOUcdIs5",
"fields" : {
"age_calculated" : [ "32 months" ] <--
}
},
...
推荐阅读
- mongodb - MongoDB 喜欢(upvote)和不喜欢(downvote)模式设计
- javascript - 带有渐变的 SVG 圆形颜色
- java - 我在我的应用程序中使用 JpaRepository。在实现类中我调用 findAll(Example
) 但它没有给我正确的回应 - javascript - django + ajax 将错误输出到表单
- java - 如何在硒中上传多个文件进行验证?
- node.js - Webapp 上的网关超时错误(504),即使我可以看到刮板未完成提取
- java - java.text.ParseException:无法解析的日期:“2020 年 3 月 11 日,星期三”
- python - 使用 python 合并具有非 NaN 值的多列
- python - 无法在 Mac 上打开空闲
- migration - SQL Server:执行从 database.schema 到另一个对象移动的脚本