假设我在名为“users”的集合中有以下文档架构:
{
name: 'John',
items: [ {}, {}, {}, ... ]
}
'items'数组包含以下格式的对象:
{
item_id: "1234",
name: "some item"
}
每个用户可以在“项目”数组中嵌入多个项目。
现在,我希望能够通过给定用户的item_id获取项目。
例如,我想获取属于名为“John”的用户的ID为“1234”的项目。
我可以使用mongoDB吗?我想利用它强大的数组索引,但我不确定你是否可以在嵌入式数组上运行查询并从数组中返回对象而不是包含它的文档。
我知道我可以使用{users.items.item_id:“1234”}来获取拥有某个项目的用户。但我想从数组中获取实际项目,而不是用户。
或者,是否有更好的方法来组织这些数据,以便我可以轻松地得到我想要的东西?我还是mongodb的新手。
感谢您提供的任何帮助或建议。
答案 0 :(得分:28)
这个问题已经很久了,但是从那时起,反应就发生了变化。使用MongoDB> = 2.2,您可以执行以下操作:
db.users.find( { name: "John"}, { items: { $elemMatch: { item_id: "1234" } } })
你将拥有:
{
name: "John",
items:
[
{
item_id: "1234",
name: "some item"
}
]
}
答案 1 :(得分:7)
有几点需要注意:
1)我发现学习MongoDB的人最难的事情是联合学习他们习惯的关系思维。您的数据模型看起来是正确的。
2)通常,您使用MongoDB执行的操作是将整个文档返回到客户端程序,然后使用客户端编程语言在客户端上搜索所需文档的一部分。
在您的示例中,您将获取整个“用户”文档,然后遍历客户端上的“items []”数组。
3)如果只想返回'items []'数组,可以使用'Field Selection'语法。有关详细信息,请参阅http://www.mongodb.org/display/DOCS/Querying#Querying-FieldSelection。不幸的是,它将返回整个'items []'数组,而不仅仅是数组的一个元素。
4)现有的Jira票证可以添加此功能:它是https://jira.mongodb.org/browse/SERVER-828 SERVER-828。看起来它已被添加到最新的2.1(开发)分支中:这意味着它将在2.2版发布时可用于生产。
答案 2 :(得分:1)
如果这是嵌入式数组,则无法直接检索其元素。检索到的文档将具有用户(根文档)的形式,但并非所有字段都可以填充(取决于您的查询)。
如果您只想检索该元素,则必须将其作为单独的文档存储在单独的集合中。它将有一个额外的字段user_id
(可以是_id
的一部分)。然后做你想做的事情是微不足道的。
示例文档可能如下所示:
{
_id: {user_id: ObjectId, item_id: "1234"},
name: "some item"
}
请注意,此结构可确保每个用户item_id
的唯一性(我不确定您是否想要这个)。