Nodejs Mongoose的find $in会把重复的数据合并起来。
Nodejs Mongoose的find $in会把重复的数据合并起来。
比如我有一个id list
var id_list = [54349edca7abe93829ea4449, 54349edca7abe93829ea4449, 5428ee861cab6e635d1927d1]
其中第一个和第二个是一样的。
我使用Model.find({ _id : {$in : id_list} }, function(err, models){})
里面返回的models只有两个数据。 但是我就是想要有三个数据。 有没有简单的办法解决这个问题? 难道我自己还要再构造一遍返回值。
多谢
Node.js Mongoose 的 find $in
不会自动去重
问题描述
假设你有一个包含重复 ID 的列表,并且你希望使用 Mongoose 的 find
方法查询这些 ID 对应的文档。然而,当你使用 $in
操作符时,Mongoose 返回的结果中不会包含重复的文档。
例如:
var id_list = [
'54349edca7abe93829ea4449',
'54349edca7abe93829ea4449',
'5428ee861cab6e635d1927d1'
];
Model.find({ _id: { $in: id_list } }, function(err, models) {
if (err) throw err;
console.log(models.length); // 输出结果为 2,而不是 3
});
在这个例子中,返回的 models
数组中只有两个文档,因为 54349edca7abe93829ea4449
出现了两次,但在查询结果中只出现了一次。
解决方案
如果你确实需要包含重复的文档,可以先进行一次查询,然后手动处理重复的逻辑。一种简单的方法是在查询之前,将数组中的每个元素都添加到结果数组中。
var id_list = [
'54349edca7abe93829ea4449',
'54349edca7abe93829ea4449',
'5428ee861cab6e635d1927d1'
];
// 使用一个 Set 来存储唯一值
var uniqueIds = new Set(id_list);
Model.find({ _id: { $in: [...uniqueIds] } }, function(err, models) {
if (err) throw err;
// 构造最终的结果数组
var finalModels = [];
id_list.forEach(function(id) {
var model = models.find(m => m._id.toString() === id);
if (model) {
finalModels.push(model);
}
});
console.log(finalModels.length); // 输出结果为 3
console.log(finalModels); // 输出完整的模型数组
});
解释
- 使用 Set 去重:首先,我们使用 JavaScript 的
Set
数据结构来去除id_list
中的重复项。Set
只允许存储唯一的值。 - 查询数据库:然后,我们使用
Set
中的唯一值作为查询条件,执行find
查询。 - 手动添加重复项:最后,我们遍历原始的
id_list
,检查每个 ID 是否存在于查询结果中。如果存在,则将其添加到最终的结果数组finalModels
中。
这种方法虽然稍微复杂一些,但能够确保所有指定的 ID(包括重复的)都能被正确地包含在查询结果中。
自己处理吧
var _ = require(‘lodash’); var id_list = [‘54349edca7abe93829ea4449’, ‘5428ee861cab6e635d1927d1’], dup_id = ‘54349edca7abe93829ea4449’; Model.find({ _id : {$in : id_list} }, function(err, docs){ var dup_index = _.findIndex(docs, {id : dup_id}); var dup_doc = _.cloneDeep(docs[dup_index]); // more … });
在使用 Mongoose 的 find
方法时,通过 $in
操作符查询数据库中的文档,如果查询条件中的某些 ID 是重复的,Mongoose 会从数据库中查询出唯一的结果。这是因为 MongoDB 本身只存储唯一的文档记录。
如果你想在查询结果中保留重复的 ID,你需要在客户端处理这些重复项。可以通过在查询后手动处理这些重复项来实现。
以下是一个示例代码,展示如何在查询后处理重复的 ID:
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
// 假设有一个简单的模型
const MyModel = mongoose.model('MyModel', new Schema({
name: String
}));
// 示例ID列表
var id_list = [
'54349edca7abe93829ea4449',
'54349edca7abe93829ea4449',
'5428ee861cab6e635d1927d1'
];
// 查询数据库
MyModel.find({ _id: { $in: id_list } }, function (err, models) {
if (err) {
console.error(err);
return;
}
// 使用一个新的对象数组来保存查询结果,确保包含重复项
const resultModels = [];
const foundIds = [];
for (let i = 0; i < id_list.length; i++) {
if (!foundIds.includes(id_list[i])) {
// 查找与id_list中相同的模型,并添加到结果中
const model = models.find(model => model._id.toString() === id_list[i]);
if (model) {
resultModels.push(model);
foundIds.push(id_list[i]);
}
}
}
console.log(resultModels);
});
在这个示例中,我们首先定义了一个包含重复 ID 的数组 id_list
。然后,我们使用 find
方法查询数据库。查询结果会过滤掉重复的 ID,我们通过遍历 id_list
并检查是否已经找到了相同的 _id
来确保所有 ID 都被包括在结果中。最后,我们将这些模型保存在一个新的数组 resultModels
中,并输出结果。这样,即使在数据库中存在重复的 ID,你仍然可以得到包含重复项的结果。