使用MongoDB中的$ all匹配数组中数组中的所有元素

时间:2014-12-12 15:31:13

标签: mongodb mongodb-query

我有一份文件,其中包含以下文件:

{ "f" : [ [ 1, 2, 3], [4, 5, 6] ] } // should match because of [1, 2, 3]
{ "f" : [ [ 2, 1, 3], [4, 5, 6] ] } // should match because of [2, 1, 3]
{ "f" : [ [ 1, 2, 4], [4, 5, 6] ] } // should NOT match

在这个集合中,我希望匹配文档,这些文档在" f"的一个数组中包含一个包含1,2和3的数组。字段。

到目前为止我已尝试过:

db.mytest.find({ f: { $elemMatch: { $all: [1,2,3] } } } )

我希望这个查询有效,但我不明白为什么不这样做。我不匹配任何文件。

db.mytest.find({ f: { $elemMatch: { $elemMatch: { $all: [1,2,3] } } } })

这也行不通。

db.mytest.find({ f: { $all: [[1,2,3]] } })

这可行,但元素必须按照确切的顺序排列。我希望能够匹配输入数组也是2,1,3。一种可能的解决方案必须是始终按升序存储元素并使用此查询。

db.mytest.find({ f: { $elemMatch: { $elemMatch: { $in: [1, 2, 3] } } } })

这有效但它匹配包含1,2或3中任何一个的所有文档。我只想要在单个数组中包含正好1,2和3的文档。

我在寻找什么查询?

3 个答案:

答案 0 :(得分:2)

似乎运算符在嵌入式数组的情况下执行精确匹配。不是最令人满意或最佳的解决方案(您需要使用集合中的记录对其进行测试),但一种方法是通过服务器端的聚合管道进行测试。

  • Project每个文件的额外字段代表" f"值。
  • unwind实际的" f"字段,以便我们可以匹配单个数组 元件。
  • match文件" f"包含输入中的所有值 阵列。
  • project返回原始文档的临时字段。

代码:

db.mytest.aggregate([
{$project:{"temp":"$f","f":1}},    // maintain a temporary variable for projection
{$unwind:"$f"},                    // f:[1,2,3] f:[4,5,6] become separate records.
{$match:{"f":{$all:[1,2,3]}}},     // use $all to match all the elements. 
{$project:{"f":"$temp"}}           // project the temporary variable.
])

答案 1 :(得分:1)

您正在查找f包含[1, 2, 3]的文档。试试db.mytest.find({f: {$in: [[1, 2, 3]]}})

不幸的是,找到所有可能排列的最简单方法是在程序中构建它们(如果您使用的是Python,itertools.permutations将为您执行此操作)并更改$in查询到[[1, 2, 3], [2, 1, 3], ...]。很糟糕。

答案 2 :(得分:1)

如何生成数组的所有排列并在查询中使用?像这样的东西:

db.mytest.find({$or : [{f: {$all : [[1,2,3]] }}, {f: {$all : [[2,1,3]]}}, {f: {$all: [[3,1,2]]}}]})

也许这不是有效的方式。