【发布时间】:2020-01-25 14:19:04
【问题描述】:
我正在使用 MongoDB 为我的应用程序创建类似的功能。我最近偶然发现了一个问题。
我喜欢的代码:
async function like(articleId, userId) {
const db = await makeDb();
return new Promise((resolve, reject) => {
const result = db.collection(collectionName).findOneAndUpdate(
{ articleId: ObjectID(articleId) },
{
$setOnInsert: {
articleId: ObjectID(articleId),
creationDate: new Date()
},
$addToSet: { likes: ObjectID(userId) }
},
{ upsert: true }
);
resolve(result);
});
它的作用:
- 如果集合中没有文档,则创建一个并填写所有字段
- 如果存在文档,则仅使用新的用户 ID 更新
likes数组
这按预期工作并且没有问题,感谢$addToSet 我没有任何重复等。
但是,在执行上述代码并返回 result 之后,我需要做一些额外的事情,为了让它工作,我需要知道 Mongos $addToSet 是否确实改变了任何东西。
简而言之:
- 如果新的 userId 已添加到
likes数组中,我想做点什么 - 如果 userId 已经在
likes数组中并且$addToSet没有改变任何东西,我不想采取任何行动。
有没有办法区分$addToSet是否做了什么?
结果的当前console.log() 如下所示:
{
lastErrorObject: { n: 1, updatedExisting: true },
value: { _id: 5e2c47c57bb5183d80dce14f,
articleId: 5da4d1365217baf52fbcd76a,
creationDate: 2020-01-25T13:51:01.928Z,
likes: [ 5d750b677d8edfc08af8a527 ]
},
ok: 1
}
我想到的一件事(但在性能方面非常糟糕)是在更新前比较 likes 数组是否包含用户 ID 和 javascript includes 方法。
有更好的想法吗?
【问题讨论】:
-
所以你想确保
addToSet没有删除/更改数组中的任何其他元素,除了添加新的唯一用户ID 或者如果它是重复的则不添加它?所以它不会影响数组中现有的重复元素/元素.. -
@srinivasy 我认为以上都不是:P 我只想知道
addToSet是否做了任何事情。addToSet工作正常,问题是有两个选项: 1. 我想添加用户 X,用户 X 不在 likes 数组中,addToSet通过添加用户 X 更新对象,返回更新后的对象。 2.我要添加用户X,用户X在likes数组中,addToSet没有效果,返回更新的(本例与旧的相同)对象。我想区分这两种情况,并对它们做出不同的反应。所以如果(1.)发生了我想做点什么,但是如果(2.)发生了我什么都不想做。 -
所以从查询的输出中你会得到`n: 1, updatedExisting: true`通过它你可以知道它是否更新了,所以addToSet推了一个新元素!!跨度>
-
是的......我虽然完全一样,但遗憾的是由于一些奇怪的原因并非如此,即使
addToSet什么也没做,它总是返回{ n:1 and updatedExisting: true }:( -
也许它反映到 nMatched 而不是 nUpdated
标签: javascript node.js mongodb mongodb-query