我正在构建一个用于存储电影/电视节目的基本crud应用程序。我正在使用elasticsearch的2.4.4版,因为我的项目经理选择了这个版本。我正在使用express框架和本地elasticsearch nodejs驱动程序。
目前这就是我的映射对于"标题" "标题的索引"类型。
client.indices.create({
index: "titles",
body: {
"mappings": {
"title": {
"properties": {
"seriesName": { "type": "string", "index": "not_analyzed" },
"seriesEpisodeNumber": { "type": "long", "index": "not_analyzed" },
"seriesEpisodeTitle": { "type": "string", "index": "not_analyzed" },
"isDeleted": { "type": "boolean", "index": "not_analyzed" }
}
}
}
}
}).
我想在我的服务器上有一个端点,用于通过id更新文档。这就是我到目前为止这个终点所用的#34; POST / api / titles /:titleID / updateTitleByID"
titlesController.updateTitleByID = function(req,res){
const titleID = req.params.titleID;
es.updateByQuery({
index: "titles",
type: "title",
body: {
query: {
bool: {
must: [{
term: {
_id: titleID
}},{
term: {
isDeleted: false
}}]
}
},
script: {
inline: "ctx._source.seriesName = seriesName;ctx._source.seriesEpisodeNumber = seriesEpisodeNumber; ctx._source.seriesEpisodeTitle = seriesEpisodeTitle;",
params: { ...req.body }
}
}}).then(results => {
logger.info(results);
res.status(200).json({
message: "OK"
});
}).catch(err => {
logger.error(err);
res.status(500).json({
error: "Internal server error"
});
});
};
我想要实现的是使用我从req.body获得的内容来更新文档。例如,如果我从请求正文中获得了一个seriesName I.这只是我想要更新的内容,其余部分保持不变。我如何实现这一目标?
编辑:这是完整的堆栈跟踪
Error: [remote_transport_exception] [Agon][127.0.0.1:9300][indices:data/write/update[s]]
at respond (/home/natealcedo/Projects/digitalfolks.hooq/node_modules/elasticsearch/src/lib/transport.js:289:15)
at checkRespForFailure (/home/natealcedo/Projects/digitalfolks.hooq/node_modules/elasticsearch/src/lib/transport.js:248:7)
at HttpConnector.<anonymous> (/home/natealcedo/Projects/digitalfolks.hooq/node_modules/elasticsearch/src/lib/connectors/http.js:164:7)
at IncomingMessage.wrapper (/home/natealcedo/Projects/digitalfolks.hooq/node_modules/lodash/lodash.js:4968:19)
at emitNone (events.js:91:20)
at IncomingMessage.emit (events.js:186:7)
at endReadableNT (_stream_readable.js:974:12)
at _combinedTickCallback (internal/process/next_tick.js:74:11)
at process._tickDomainCallback (internal/process/next_tick.js:122:9)
答案 0 :(得分:1)
如果您想要更新单个文档,则不需要使用逐个查询的端点,Update API绰绰有余,因为它支持partial updates,这正是你追求的是什么。您需要使用update
call代替:
titlesController.updateDocByID = function(req,res){
const titleID = req.params.titleID;
const partialFields = req.body;
// TODO do some validations on the received fields
es.update({
index: "titles",
type: "title",
id: titleID,
body: {
doc: partialFields
}}).then(results => {
logger.info(results);
res.status(200).json({
message: "OK"
});
}).catch(err => {
logger.error(err);
res.status(500).json({
error: "Internal server error"
});
});
};
如果您只需要在isDeleted
标志为false时更新文档,那么您可以使用相同的API调用但使用脚本,如下所示:
titlesController.updateDocByID = function(req,res){
const titleID = req.params.titleID;
const partialFields = req.body;
// TODO do some validations on the received fields
es.update({
index: "titles",
type: "title",
id: titleID,
body: {
script: "if (!ctx._source.isDeleted) { ctx._source.putAll(params.partialFields) }",
params: {partialFields: partialFields}
}}).then(results => {
logger.info(results);
res.status(200).json({
message: "OK"
});
}).catch(err => {
logger.error(err);
res.status(500).json({
error: "Internal server error"
});
});
};
如果您使用第二种方法,则需要在elasticsearch.yml
配置文件中enable dynamic scripting。