我需要更新现有数据。有比这更好的方法吗检索旧数据->修改旧数据->删除旧索引->创建新索引->大容量插入新数据这看起来有点愚蠢。此外,每个index
的store.size
大约高出2倍。我不明白为什么会这样。
直接扩充修改后的数据不起作用:docs.count
加倍。
有什么想法吗?
更新
这是我的批量插入:
var dataPointsBulkIndexOperationsPerBatchId = data.Select(
item => new BulkIndexOperation<T>(item)
{
Index = indexName
});
var allBulksRequest = new BulkRequest
{
Operations = new BulkOperationsCollection<IBulkOperation>(dataPointsBulkIndexOperationsPerBatchId),
Refresh = Refresh.True
};
if (allBulksRequest.Operations.Any())
{
var bulkResponse = elasticClient.Bulk(allBulksRequest);
bulkResponse.AssertResponseIsValidAndSuccessful();
}
对于在一个请求中更新多个文档,基本上有两个选项:
1.具有更新操作的批量API
使用批量API并发送一批更新操作。每个更新操作都公开了与更新API相同的选项,因此可以执行部分更新、脚本更新等
脚本更新的示例
var client = new ElasticClient();
var updates = new[] {
new { Id = 1, Counter = 3 },
new { Id = 2, Counter = 6 },
new { Id = 3, Counter = 5 },
new { Id = 4, Counter = 4 },
};
var bulkResponse = client.Bulk(b => b
.Index("my_index")
.UpdateMany(updates, (descriptor, update) => descriptor
.Id(update.Id)
.Script(s => s
.Source("ctx._source.counter += params.counter")
.Params(p => p
.Add("counter", update.Counter)
)
)
)
);
其发送以下请求
POST http://localhost:9200/my_index/_bulk
{"update":{"_id":1}}
{"script":{"source":"ctx._source.counter += params.counter","params":{"counter":3}}}
{"update":{"_id":2}}
{"script":{"source":"ctx._source.counter += params.counter","params":{"counter":6}}}
{"update":{"_id":3}}
{"script":{"source":"ctx._source.counter += params.counter","params":{"counter":5}}}
{"update":{"_id":4}}
{"script":{"source":"ctx._source.counter += params.counter","params":{"counter":4}}}
使用脚本更新时,您可以通过ctx._source
访问脚本中的_source
文档,因此本例在更新操作中将源文档的counter
字段增加counter
参数的值。默认的脚本语言称为Painless,脚本可以根据需要进行复杂处理。建议如上所述对内联脚本进行参数化,以允许Elasticsearch缓存和重用编译脚本产生的编译单元。
对于批量更新,您需要知道要更新的文档的id,以便形成批量更新操作。
2.通过查询API更新
通过查询更新API,您可以对与查询匹配的一组文档执行脚本更新。
脚本化更新对每个匹配的文档执行相同的脚本。执行脚本更新时,按查询更新和批量更新之间的一个关键区别是,每次文档更新都不能使用不同的参数值对按查询更新进行参数化;所有更新都执行相同的脚本更新。
通过查询更新的示例
var updateByQueryResponse = client.UpdateByQuery<object>(b => b
.Index("my_index")
.Query(q => q
.Ids(ids => ids
.Values(1,2,3,4)
)
)
.Script(s => s
.Source("ctx._source.counter += params.counter")
.Params(p => p
.Add("counter", 1)
)
)
);
其发送以下请求
POST http://localhost:9200/my_index/_update_by_query?pretty=true
{
"query": {
"ids": {
"values": [1, 2, 3, 4]
}
},
"script": {
"source": "ctx._source.counter += params.counter",
"params": {
"counter": 1
}
}
}
与脚本化批量更新类似,您可以通过ctx._source
访问脚本中的_source
文档。
通过查询更新,您不需要知道要更新的文档的id;要更新的文档将通过匹配所提供的查询而成为目标,该查询可以是用于更新所有文档的match_all
查询。