我正在使用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);
});
它的作用:
likes
数组[此操作正常,没有问题,这要感谢$addToSe
t我没有任何重复等。
但是在执行了上述代码并返回了result
之后,我需要做一些额外的事情,并且要使其正常工作,我需要知道Mongos $addToSet
是否确实进行了任何更改。
简而言之:
likes
数组中,我想做某事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
数组,如果该数组包含带有javascript includes
方法的userID。
还有更好的主意吗?
我找到了解决方案!
99%的功劳归给Neil Lunn
,用于此答案:https://stackoverflow.com/a/44994382/2175228
它使我走上了正确的轨道。我放弃了findOneAndUpdate
方法,转而使用updateOne
方法。查询参数等都保持不变,只是方法名称发生了变化,显然该方法的结果类型也是如此。
updateOne
方法的问题在于它不返回已更新的对象(或旧的对象)。但是它确实返回了upsertedId
,这是我所需要的唯一条件。
所以最后您得到的是一个很长的CommandResult
对象,其开头为:
CommandResult {
result: { n: 1, nModified: 0, ok: 1 },
(...)
}
但是当我仔细观察时,我发现该对象恰好具有我一直需要的字段:
modifiedCount: 0,
upsertedId: null, // if object was inserted, this field will contain it's ID
upsertedCount: 0,
matchedCount: 1
所以您需要做的就是从CommandResult
对象中获取所需的零件,然后继续;)
更改后的我的代码:
async function like(articleId, userId) {
const db = await makeDb();
return new Promise((resolve, reject) => {
db.collection(collectionName)
.updateOne(
{ articleId: ObjectID(articleId) },
{
$setOnInsert: {
articleId: ObjectID(articleId),
creationDate: new Date()
},
$addToSet: { likes: ObjectID(userId) }
},
{ upsert: true }
)
.then(data => {
// wrap the content that You need
const result = {
upsertedId: data.upsertedId,
upsertedCount: data.upsertedCount,
modifiedCount: data.modifiedCount
};
resolve(result);
});
});
}
希望这个答案将来会帮助遇到类似问题的人:)