我的mongoDB集合中有3个简单的文档:

{
    _id: ObjectId('1'),
    item: 'test1',
    tags: [ 'red', 'blank' ]
  },
 {
    _id: ObjectId('2'),
    item: 'test2',
    tags: [ 1, 2, 3, [ 'red', 'blank' ] ]
  },
 {
    _id: ObjectId('3'),
    item: 'item3',
    tags: [ 1, 2, 3, [ [ 'red', 'blank' ] ] ]
  }

当我使用这个mongoh命令时(假设我的集合在我的数据库中称为集合):

db.collection.find({tags: ['red', 'blank']})

它返回这些文档中的前两个文档.这个查询直接来自MongoDB的文档,它声明:"[This]Example查询的所有文档中,字段标记值是一个数组,其中恰好有两个元素,即按指定顺序排列的"red"和"Blank"."source

然而,在第二个文档中,我的字段‘tags’的值不是"恰好是两个元素的数组".这会导致返回的文档与我查询的值不完全相同.

第三个文档将由我使用的查询返回,所以它似乎没有递归地搜索子array.

我是否使用了错误的查询?如果是这样的话,文档中声明"...其中的字段标记值是一个恰好有两个元素的array..."就没有意义了.或者这只是一个可能的错误,因为根据他们的文档,这似乎不是他们希望该查询返回的内容.

我可以简单地过滤我的结果并获得我想要的信息,我的问题与我是否误解或使用错误的查询有关.

我还try 在atlas中使用这个查询{tags: ['red', 'blank']},它仍然返回带有_id 1和2的文档,但不返回3.

推荐答案

第三个文档不会被我使用的查询返回,所以mongoDB似乎不会递归地搜索子array.

这是正确的.


现在,让我们来了解为什么行为是这样的,Mongo迭代数据库数组中的每一项,并计算它们以查看它们是否匹配约束.

来自MongoDB源代码:

if (isArray) {
   // When the path we are comparing is a path to an array, the comparison is
   // considered true if it evaluates to true for the array itself or for any of the
   // array’s elements.

   result = make<PathComposeA>(make<PathTraverse>(result, PathTraverse::kSingleLevel),
       result);
}

这就是Mongo生成比较树语法的方式,或者当他们将其称为"AST"时,正如您从注释中看到的那样,数组有一个特殊的考虑因素来支持这种行为.

本质上,Mongo构建的比较树试图找到['red', 'blank']的匹配项,它开始遍历数据库中的array.

对于文档{tags: ['red', 'blank']},所生成的AST将遍历标签字段并将其与查询数组['red', 'blank']进行比较.由于文档的数组以与查询数组相同的顺序包含元素['red', 'blank'],因此文档将匹配查询.

对于文档{tags: [['red', 'blank']]},生成的AST还将遍历标记字段并将其与查询数组进行比较.在这种情况下,文档的数组[x1, .., ['red', 'blank'], .., xn]包含匹配查询的内部数组['red', 'blank'].

[[['red', 'blank']]]将不匹配,因为它在任何约束下都不成立.

Mongodb相关问答推荐

更新查询mongoose 中的礼宾更新字段

查找/查找单个深度嵌套文档的多个集合

用其他集合中的文档替换嵌套文档数组中的值

我无法在react 中使用 fetch 和express 从数据库中删除数据

使用特定关键字和邻近度进行查询和过滤

使用 multer 在我的 MERN 前端显示 MongoDB 图像的正确语法是什么?

使用新字段插入数据或使用 updateOne mongodb 有条件地更新

$eq 的目的是什么

PHP 无法加载动态库 (mongo.so)

使用绝对类型在 Typescript 中编写 Mongoose 的类型化模型和模式的类和接口

Mongo查找对象内最长数组的查询

pymongo 排序和 find_one 问题

如何使用sailsjs v0.10连接mongodb?

在 mongodb 的一次更新调用中推送到两个单独的数组

如何将 mongoDB 数据导出为 CSV 格式?

适用于 Windows 10 64 位的 MongoDB 下载

在安装的 MongoDB homebrew 中设置 dbpath (Mac OS)

Mongoose 版本控制:when is it safe to disable it?

使用 mongoengine 将多文档插入到 mongodb

无法从 mongodb 中删除集合