【问题标题】:Find documents whose array field contains at least n elements of a given array查找其数组字段包含给定数组的至少 n 个元素的文档
【发布时间】:2016-10-10 02:10:47
【问题描述】:

基本上就是标题所说的。

输入:myArray = 单词数组

我有一个有字段的模型 wordsCollection,是一个数组字段。

如何找到该模型的所有文档,其 wordsCollections 至少有 n 个 myArray 元素

【问题讨论】:

  • 显示 db 结构以及到目前为止您为使其工作所做的尝试。
  • 我认为问题不够清楚,我不需要提供数据库结构。我不确定mongodb是否提供了这样的API调用,所以我只是在考虑遍历所有文档....当然,听起来真的很糟糕
  • myArraywordsCollection 的项目是唯一的吗?

标签: mongodb mongoose aggregation-framework


【解决方案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,你不会仅仅因为它被否决而投赞成票。根据内容的质量投票。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-23
  • 2020-12-05
  • 1970-01-01
相关资源
最近更新 更多