Javascript 在Mongo DB中的数组中查找重复值,但它可以出现在对象外部
我想要一个查询,它将给我的用户名,其中serialNumber值是重复的。一个库中的序列号值可以存在于其他用户名库中,但不应存在于某个特定用户名库中尝试以下查询:Javascript 在Mongo DB中的数组中查找重复值,但它可以出现在对象外部,javascript,arrays,mongodb,mongodb-query,aggregation-framework,Javascript,Arrays,Mongodb,Mongodb Query,Aggregation Framework,我想要一个查询,它将给我的用户名,其中serialNumber值是重复的。一个库中的序列号值可以存在于其他用户名库中,但不应存在于某个特定用户名库中尝试以下查询: { "_id" : ObjectId("15672"), "userName" : "4567", "library" : [ { "serialNumber" : "Book_1" }, { "serialNu
{
"_id" : ObjectId("15672"),
"userName" : "4567",
"library" : [
{
"serialNumber" : "Book_1"
},
{
"serialNumber" : "Book_2"
},
{
"serialNumber" : "Book_4"
}
]
},
{
"_id" : ObjectId("123456"),
"userName" : "123",
"library" : [
{
"serialNumber" : "Book_2"
}
]
},
{
"_id" : ObjectId("1835242"),
"userName" : "13526",
"library" : [
{
"serialNumber" : "Book_7"
},
{
"serialNumber" : "Book_6"
},
{
"serialNumber" : "Book_5"
},
{
"serialNumber" : "Book_4"
},
{
"serialNumber" : "Book_3"
},
{
"serialNumber" : "Book_5"
}
]
}
另一种方法是通过$unwind
来实现这一点,但这在大型数据集上并不可取,因为它会爆炸您的收藏
测试:
或者从该链接中@Dennis的答案中,您可以尝试以下操作:
db.collection.aggregate([
/** First match stage is optional if all of your docs are of type array & not empty */
{ $match: { $expr: { $and: [{ $eq: [{ $type: "$library" }, "array"] }, { $ne: ["$library", []] }] } } },
/** Add a new field allUnique to each doc, will be false where if elements in library have duplicates */
{
$addFields: {
allUnique: {
$eq: [
{
$size:
{
$reduce: {
input: "$library.serialNumber",
initialValue: [], // start with empty array
/** iterate over serialNumber's array from library & push current value if it's not there in array, at the end reduce would produce an array with uniques */
in: { $cond: [{ $in: ["$$this", "$$value"] }, [], { $concatArrays: [["$$this"], "$$value"] }] }
}
}
},
{
$size: "$library"
}
]
}
}
},
/** get docs where allUnique: false */
{
$match: {
allUnique: false
}
},
/** Project only needed fields & remove _id which is bydefault projected */
{
$project: {
userName: 1,
_id: 0
}
}
])
测试:您可以在
库
数组字段上使用聚合运算符,这将返回唯一元素的数组(称之为库_unique
)。然后,比较library
和library\u unique
的大小($size
聚合运算符给出数组的长度)。如果大小不相等,这意味着该文档的库
数组中存在重复元素。非常感谢您,whoami,但我忘记了一点,如果库数组中没有serialNumber键,那么它仍然会给我该用户名,我不想要该用户名,您可以在查询中更新该条件吗,这将非常有帮助me@AbhishekKV:请尝试以下操作::,而不是{$ne:[“$library”,[]}
添加{$eq:[{$type:“$library.serialNumber”},“array”]}
@AbhishekKV:也许不必进行类型检查,只需检查“library.serialNumber”不是空数组即可
db.collection.aggregate([
{
$match: {
$expr: {
$and: [
{
$eq: [
{
$type: "$library"
},
"array"
]
},
{
$ne: [
"$library",
[]
]
}
]
}
}
},
{
$addFields: {
allUnique: {
$eq: [
{
$size: {
"$setUnion": [
"$library.serialNumber",
[]
]
}
},
{
$size: "$library"
}
]
}
}
},
{
$match: {
allUnique: false
}
},
{
$project: {
userName: 1,
_id: 0
}
}
])