返回不包含特定内部数组项的 MongoDB 文档

Posted

技术标签:

【中文标题】返回不包含特定内部数组项的 MongoDB 文档【英文标题】:Return MongoDB documents that don't contain specific inner array items 【发布时间】:2017-02-17 12:36:13 【问题描述】:

如何返回一组文档,每个文档都不包含内部数组中的特定项目?

我的数据方案是:

帖子:

 
    "_id" : ObjectId("57f91ec96241783dac1e16fe"), 
    "votedBy" : [
        
            "userId" : "101",
            "vote": 1
        , 
        
            "userId" : "202",
            "vote": 2
        
    ], 
    "__v" : NumberInt(0)

我想返回一组帖子,其中不包含任何 votedBy 数组项中的给定 userId。 官方文档暗示这是可能的:

MongoDB documentation: Field with no specific array index

虽然它返回一个空集(对于查找具有特定数组项的文档的更简单情况)。 似乎我必须知道正确结果集的索引,例如: votedBy.0.userId。

This 问题是我找到的最接近的问题,使用此解决方案(应用于我的方案):

db.collection.find("votedBy":  $not: $elemMatch: userId: 101    )

如果数组中唯一的内部文档与我不希望返回的内部文档匹配,则它工作正常,但在我上面指定的示例情况下,文档返回,因为它找到了 userId=202 内部文档。

澄清一下:我想返回所有文档,它们的 votedBy 数组项中没有一个具有给定的 userId。

我还尝试了一个更简单的数组,仅包含 userId 作为字符串数组,但仍然每个都收到一个 Id,搜索过程是一样的。

我尝试的另一个解决方案是为用户投票使用不同的集合,并应用查找来执行类似 SQL 的连接,但似乎有更简单的方法。

我正在使用猫鼬(node.js)。

【问题讨论】:

【参考方案1】:

内嵌userId上的用户$ne

db.collection.find('votedBy.userId': $ne: '101')

它将过滤所有具有至少一个userId = "101"元素的文档

【讨论】:

嗨@Tom,感谢您的回复。恐怕这不起作用(返回所有文件)。让我们看一个更简单的例子: 'votedBy.userId': '101' 应该只返回元素为 101 的文档,但根本不返回任何结果。在我看来,原因是它仅适用于例如“votedBy.0.userId”(我们应该迭代所有索引的地方),但在这个组合点方法中它找不到。 @Bobcat100 它正在工作,我在 3.2 版上对其进行了测试(不知道旧版本),因此请检查架构是否与问题中的完全相同并且您是否正确复制。你给出的例子和$ne 的查询不一样。查询:'votedBy.userId': '101' 将返回所有包含至少一个元素为 '101' 的文档,而我的答案中的查询将返回没有 '101' 元素的文档。 该示例确实不同,以表明在更简单的查询中, votedBy.userId 不起作用。我不认为我有不同的版本,因为我使用的是最新的 Azure documentDB,应该支持这个版本。您能否检查我的示例: 'votedBy.userId': '101' 返回包含 101 的文档还是 [] 答案?谢谢,巴拉克。 在您的示例架构中,'votedBy.userId': '101' 返回包含 101 的文档,我的回答是:'votedBy.userId': $ne: '101' 它返回 [](无结果)。这就是你想要的。

以上是关于返回不包含特定内部数组项的 MongoDB 文档的主要内容,如果未能解决你的问题,请参考以下文章

返回文档,其中数组元素包含输入数组的所有值 | MongoDB

MongoDb:查找具有重复项的精确数组匹配

MongoDB:带有数组的文本索引,只有第一个词被索引

Mongodb find() 只包含非空数组

MongoDB Async - 查找或创建文档;返回它们的数组

在 Mongoose/MongoDB 的文档中过滤数组、子文档、数组、文档