Node.js 更新MongoDB中的嵌套数组对象
我必须在NodeJS应用程序中处理以下类型的对象(使用mongodb驱动程序): 我每2分钟收到一次上述数据。 我想:Node.js 更新MongoDB中的嵌套数组对象,node.js,mongodb,Node.js,Mongodb,我必须在NodeJS应用程序中处理以下类型的对象(使用mongodb驱动程序): 我每2分钟收到一次上述数据。 我想: 如果收到的数据的id尚未出现在MongoDB上,请执行插入 如果接收到的数据中有一个样本对象的日期(t属性)尚未出现,则向该样本对象添加属性(例如,不同传感器的读数) 如果接收到的数据的样本对象的日期(t属性)尚未出现在样本数组中,则添加此新对象 我想用MongoDB服务器可能的少量往返次数来完成上面描述的工作。 我希望已经足够清楚了。 有什么建议吗? 提前谢谢。这是我的建议,
提前谢谢。这是我的建议,这不是正确的答案。您将需要处理查询部分。下面的查询应该适用于1和3,对于2,您将不得不到处玩
db.collection.updateOne(
{ "id" : "105-20090412", "samples.t": <Date> },
{ $push: { "samples" : <sample> } },
{ $setOnInsert: { station: <station> } },
{ upsert: true }
);
db.collection.updateOne(
{“id”:“105-20090412”,“samples.t”:},
{$push:{“样本”:},
{$setOnInsert:{station:}},
{upsert:true}
);
参考资料:
我终于找到了以下解决方案,也许不是最有效的:
try {
const db = client.db(dbName);
const collection = db.collection(collectionName);
// retrive id, station, date and samplesToAdd as separate objects
let {
id,
...dataToInsert
} = data
//id = new ObjectID(id)
const queryBy_id = {
_id: id
}
// first check if doc exists
let res_query = await collection.findOne(queryBy_id)
// if doc does not exists then insert a new one
if (!res_query) {
res_insert = await collection.insertOne({
_id: id,
...dataToInsert
})
return res_insert;
} else {
// retrive samples from initial query
let current_samples = res_query.samples
// check if sample in dataToInsert yet exists
// use getTime to correctly compare dates
let idx = current_samples.findIndex(x => x.t.getTime() == dataToInsert.samples[0].t.getTime())
if (idx >= 0) {
// find index of sample to update
let current_t = current_samples[idx].t
// merge data yet stored with new one
current_samples.data = {
...current_samples[idx].data,
...dataToInsert.samples[0].data
}
let resUpdateSample = await collection.updateOne({
_id: id,
'samples.t': current_t
}, {
$set: {
'samples.$.data': current_samples.data
}
})
return resUpdateSample
} else {
// add data to samples array
let resAddToSamples = await collection.updateOne({
_id: id
}, {
$push: {
samples: dataToInsert.samples[0]
}
})
return resAddToSamples
}
}
} catch (err) {
logger.error(err);
}
我怎样才能改进它?
谢谢。谢谢,但它不起作用,我认为推动部分有问题。
try {
const db = client.db(dbName);
const collection = db.collection(collectionName);
// retrive id, station, date and samplesToAdd as separate objects
let {
id,
...dataToInsert
} = data
//id = new ObjectID(id)
const queryBy_id = {
_id: id
}
// first check if doc exists
let res_query = await collection.findOne(queryBy_id)
// if doc does not exists then insert a new one
if (!res_query) {
res_insert = await collection.insertOne({
_id: id,
...dataToInsert
})
return res_insert;
} else {
// retrive samples from initial query
let current_samples = res_query.samples
// check if sample in dataToInsert yet exists
// use getTime to correctly compare dates
let idx = current_samples.findIndex(x => x.t.getTime() == dataToInsert.samples[0].t.getTime())
if (idx >= 0) {
// find index of sample to update
let current_t = current_samples[idx].t
// merge data yet stored with new one
current_samples.data = {
...current_samples[idx].data,
...dataToInsert.samples[0].data
}
let resUpdateSample = await collection.updateOne({
_id: id,
'samples.t': current_t
}, {
$set: {
'samples.$.data': current_samples.data
}
})
return resUpdateSample
} else {
// add data to samples array
let resAddToSamples = await collection.updateOne({
_id: id
}, {
$push: {
samples: dataToInsert.samples[0]
}
})
return resAddToSamples
}
}
} catch (err) {
logger.error(err);
}