Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays MongoDB:在嵌入式数组中查询和检索对象?_Arrays_Mongodb - Fatal编程技术网

Arrays MongoDB:在嵌入式数组中查询和检索对象?

Arrays MongoDB:在嵌入式数组中查询和检索对象?,arrays,mongodb,Arrays,Mongodb,假设我在一个名为“用户”的集合中有以下文档架构: { name: 'John', items: [ {}, {}, {}, ... ] } “items”数组包含以下格式的对象: { item_id: "1234", name: "some item" } 每个用户可以在“项”数组中嵌入多个项 现在,我希望能够通过给定用户的item_id获取一个item 例如,我想获取id为“1234”的项目,该项目属于名为“John”的用户 我可以用mongoDB做这个吗?

假设我在一个名为“用户”的集合中有以下文档架构:

{
    name: 'John',
    items: [ {}, {}, {}, ... ]
}
“items”数组包含以下格式的对象:

{
    item_id: "1234",
    name: "some item"
}
每个用户可以在“项”数组中嵌入多个项

现在,我希望能够通过给定用户的item_id获取一个item

例如,我想获取id为“1234”的项目,该项目属于名为“John”的用户

我可以用mongoDB做这个吗?我想利用它强大的数组索引,但我不确定是否可以在嵌入式数组上运行查询,并从数组而不是包含它的文档返回对象

我知道我可以使用{users.items.item_id:“1234”}获取具有特定项的用户。但我想从数组中获取实际项,而不是从用户中获取

或者,是否有更好的方法来组织这些数据,以便我可以轻松地得到我想要的?我对mongodb还是相当陌生的


感谢您提供的任何帮助或建议。

如果这是一个嵌入式数组,则无法直接检索其元素。检索到的文档将具有用户(根文档)的形式,尽管并非所有字段都可以填写(取决于您的查询)

如果只想检索该元素,则必须将其作为单独的文档存储在单独的集合中。它将有一个附加字段,
user\u id
(可以是
\u id
的一部分)。那么做你想做的事就很简单了

示例文档可能如下所示:

{
    _id: {user_id: ObjectId, item_id: "1234"},
    name: "some item"
}

请注意,此结构可确保每个用户的
项目id的唯一性(我不确定您是否想要此项)。

关于此,有几点需要注意:

1) 我发现,对于学习MongoDB的人来说,最困难的事情是不学习他们习惯的关系思维。您的数据模型看起来是正确的

2) 通常,使用MongoDB所做的是将整个文档返回到客户端程序中,然后使用客户端编程语言在客户端搜索所需的文档部分

在您的示例中,您将获取整个“user”文档,然后在客户端迭代“items[]”数组

3) 如果只想返回“items[]”数组,可以使用“Field Selection”语法。有关详细信息,请参阅。不幸的是,它将返回整个“items[]”数组,而不仅仅是数组中的一个元素


4) 有一个现有的Jira票证可以添加此功能:它是SERVER-828。它看起来像是被添加到了最新的2.1(开发)分支中:这意味着它将在2.2版发布时可供生产使用。

这个问题很老了,但自那时起,答案已经改变了。使用MongoDB>=2.2,您可以执行以下操作:

db.users.find( { name: "John"}, { items: { $elemMatch: { item_id: "1234" } } })
你将有:

{
   name: "John",
   items: 
   [ 
       {
         item_id: "1234",
         name: "some item"
       }
   ]
}

谢谢你的回答。我本想避免使用两个集合来进行此操作,但这似乎是唯一的方法。可能重复Hello,@Nebs,您能否查看已接受的答案并更改它?因为有一个解决方案可以解决这个问题,而不需要在较新的mongodb版本中使用两个单独的集合。这是OP问题的最佳答案,我希望他看到并更改它,否则许多人会看到公认的答案,认为没有两个集合就没有解决方案。