如何使用 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}),{}));
我有一个名为 "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}),{}));