查找其数组字段包含给定数组的至少 n 个元素的文档
Posted
技术标签:
【中文标题】查找其数组字段包含给定数组的至少 n 个元素的文档【英文标题】:Find documents whose array field contains at least n elements of a given array 【发布时间】:2016-10-10 02:10:47 【问题描述】:基本上就是标题所说的。
输入:myArray
= 单词数组
我有一个有字段的模型
wordsCollection
,是一个数组字段。
如何找到该模型的所有文档,其 wordsCollections
至少有 n 个 myArray
元素
【问题讨论】:
显示 db 结构以及到目前为止您为使其工作所做的尝试。 我认为问题不够清楚,我不需要提供数据库结构。我不确定mongodb是否提供了这样的API调用,所以我只是在考虑遍历所有文档....当然,听起来真的很糟糕myArray
和 wordsCollection
的项目是唯一的吗?
【参考方案1】:
假设我们的集合中有以下文档:
"_id" : ObjectId("5759658e654456bf4a014d01"), "a" : [ 1, 3, 9, 2, 9, 0 ]
"_id" : ObjectId("5759658e654456bf4a014d02"), "a" : [ 0, 8, 1 ]
"_id" : ObjectId("5759658e654456bf4a014d03"), "a" : [ 0, 8, 432, 9, 34, -3 ]
"_id" : ObjectId("5759658e654456bf4a014d04"), "a" : [ 0, 0, 4, 3, 2, 7 ]
以及下面的输入数组和n = 2
var inputArray = [1, 3, 0];
我们可以使用聚合框架返回数组字段至少包含给定数组的 n 个元素的文档。
$match
只选择数组长度大于或等于n
的文档。这减少了管道中要处理的数据量。
$redact
管道运算符使用逻辑条件处理,使用 $cond
运算符和特殊操作 $$KEEP
来“保留”逻辑条件为真的文档或 $$PRUNE
来“丢弃”其中的文档条件为假。
在我们的例子中,条件是$gte
,如果我们使用$setIntersection
运算符计算的两个数组的交集的$size
大于或等于2
,则返回true。
db.collection.aggregate(
[
"$match": "a.1": "$exists": true ,
"$redact":
"$cond": [
"$gte": [
"$size": "$setIntersection": [ "$a", inputArray ] ,
2
],
"$$KEEP",
"$$PRUNE"
]
]
)
产生:
"_id" : ObjectId("5759658e654456bf4a014d01"), "a" : [ 1, 3, 9, 2, 9, 0 ]
"_id" : ObjectId("5759658e654456bf4a014d02"), "a" : [ 0, 8, 1 ]
"_id" : ObjectId("5759658e654456bf4a014d04"), "a" : [ 0, 0, 4, 3, 2, 7 ]
【讨论】:
您的解决方案很棒。我从中学到了很多mongodb。谢谢 :)【参考方案2】:使用聚合。
在$match聚合管道中,可以使用$size和$gte
【讨论】:
我会尝试,如果可以避免不断更新“计数”字段,这可能会非常有用!不知道为什么你被否决了,我投了反对票 @libik:我试试看 这里你不能在$match
中使用$size
。我没有看到这如何解决这里的问题。顺便说一句@JulienLeray,你不会仅仅因为它被否决而投赞成票。根据内容的质量投票。以上是关于查找其数组字段包含给定数组的至少 n 个元素的文档的主要内容,如果未能解决你的问题,请参考以下文章
2021-11-01:寻找重复数。给定一个包含 n + 1 个整数的数组 nums ,其数字都在 1 到 n 之间(包括 1 和 n),可知至少存在一个重复的整数。假设 nums 只有 一个重复的整数