如何使用 node.js 比较 mongoDB ObjectIds 并删除文档数组中的重复项?

How to compare mongoDB ObjectIds & remove duplicates in an array of documents using node.js?

我有一个名为 "doc" 的数组,其中包含一个列表,其中一些包含相同的引用对象 ID,我必须删除该重复项,但代码的 none 正在运行,因为我正在根据 ref object id 进行过滤,它是 object 的形式。我必须访问对象内部的 id 并根据该对象 id 对其进行过滤。这里的 userId 是参考对象 ID。

Answer.find({'blockId': questId}, (err, doc) => {
        if(doc!=null){
            userId = 0;
            userList = [];
            userIdd = 0;
            uslist = [];
            for(var i = 0; i<doc.length; i++){
                if(userId != doc[i].userId){
                    userIdList.push({'userId':doc[i].userId});
                    userId = doc[i].userId;
                }
            }
        }else{

        }
    });

如果您从数据库中获取 doc[i].userId 字段值 ObjectId(),请尝试以下操作:

Answer.find({ 'blockId': questId }, (err, doc) => {
    if (err) {
        // return here itself
    }
    let userId = '';
    let userIdList = [];
    if (doc.length) {
        for (var i = 0; i < doc.length; i++) {
            /** Since we're using mongoose use `.toHexString()` to convert to string & compare,
               if you're using mongoDB driver use `toString()` to convert to string */.
            if (userId != (doc[i].userId).toHexString()) {
                userIdList.push({ 'userId': doc[i].userId });
                userId = (doc[i].userId).toHexString();
            }
        }
    } else {
       console.log('No matching answers found for blockId ::', questId)
    }
})

以上代码应通过 Node.Js 运行,以防万一如果您的目的只是为了获得独特的 userId,请尝试使用此代码,因为它有助于在 DB 本身中快速实现目标:

Answer.aggregate({$match : {"blockId" : 1}},
{$group : {_id : {blockId: '$blockId'},userIds: {$addToSet : '$userId'} }}).lean(true).exec((err, doc)=> {})

收集数据:

/* 1 */
{
    "_id" : ObjectId("5e103f0b400289966e01dc47"),
    "blockId" : 1,
    "userId" : ObjectId("5dfeac7b400289966e2042c7")
}

/* 2 */
{
    "_id" : ObjectId("5e103f34400289966e01e1f9"),
    "blockId" : 1,
    "userId" : ObjectId("5dfeac7b400289966e2042c5")
}

/* 3 */
{
    "_id" : ObjectId("5e103f4a400289966e01e56c"),
    "blockId" : 1,
    "userId" : ObjectId("5dfeac7b400289966e2042c7")
}

/* 4 */
{
    "_id" : ObjectId("5e103f51400289966e01e678"),
    "blockId" : 1,
    "userId" : ObjectId("5dfeac7b400289966e2042c6")
}

/* 5 */
{
    "_id" : ObjectId("5e103f57400289966e01e793"),
    "blockId" : 1,
    "userId" : ObjectId("5dfeac7b400289966e2042c1")
}

/* 6 */
{
    "_id" : ObjectId("5e103f61400289966e01e92b"),
    "blockId" : 2,
    "userId" : ObjectId("5dfeac7b400289966e2042c9")
}

/* 7 */
{
    "_id" : ObjectId("5e1040c3400289966e021168"),
    "blockId" : 1,
    "userId" : ObjectId("5dfeac7b400289966e2042c5")
}

结果:

/* 1 */
/** Duplicates removed */
{
    "_id" : {
        "blockId" : 1
    },
    "userIds" : [ 
        ObjectId("5dfeac7b400289966e2042c1"), 
        ObjectId("5dfeac7b400289966e2042c6"), 
        ObjectId("5dfeac7b400289966e2042c5"), 
        ObjectId("5dfeac7b400289966e2042c7")
    ]
}

或者如果您只是想使用 .find() 并且仍然在 node.js 中使用它,同样如果您的操作都是关于唯一用户 ID 的,那么至少在您的代码中添加投影以便从数据库中仅检索需要的字段:

Answer.find({ 'blockId': questId }, {_id :0, 'blockId':1, userId:1 }, (err, doc) => { })

我有一个简单的解决方案。 如果 'doc' 是包含重复项的数组。

 userIdList = [];
 userIdList = Object.values(doc.reduce((acc,cur)=>Object.assign(acc,{[cur.userId.toString()]:cur}),{}));