我有一个包含数组的文档:
{
_id: ObjectId("515e10784903724d72000003"),
association_chain: [
{
name: "Product",
id: ObjectId("4e1e2cdd9a86652647000003")
}
],
//...
}
我正在尝试在集合中搜索name
数组中第一项的association_chain
与给定值匹配的文档。
我怎样才能使用Mongoid?或者,如果您只知道如何使用MongoDB完成此操作,如果您发布示例,那么我可能会想出如何使用Mongoid。
答案 0 :(得分:5)
使用位置运算符。您可以使用.0
(第二个使用.1
等)查询数组的第一个元素。
> db.items.insert({association_chain: [{name: 'foo'}, {name: 'bar'}]})
> db.items.find({"association_chain.0.name": "foo"})
{ "_id" : ObjectId("516348865862b60b7b85d962"), "association_chain" : [ { "name" : "foo" }, { "name" : "bar" } ] }
您可以看到位置运算符生效,因为在第二个元素中搜索foo
不会返回命中...
> db.items.find({"association_chain.1.name": "foo"})
>
...但是搜索bar
会。
> db.items.find({"association_chain.1.name": "bar"})
{ "_id" : ObjectId("516348865862b60b7b85d962"), "association_chain" : [ { "name" : "foo" }, { "name" : "bar" } ] }
您甚至可以索引此特定字段,而无需索引所有关联链文档的所有名称:
> db.items.ensureIndex({"association_chain.0.name": 1})
> db.items.find({"association_chain.0.name": "foo"}).explain()
{
"cursor" : "BtreeCursor association_chain.0.name_1",
"nscanned" : 1,
...
}
> db.items.find({"association_chain.1.name": "foo"}).explain()
{
"cursor" : "BasicCursor",
"nscanned" : 3,
...
}
答案 1 :(得分:2)
两种方法:
1)如果您已经知道您只对“association_chain”中出现的第一个产品名称感兴趣,那么这样做会更好:
db.items.find("association_chain.0.name":"something")
请注意,这不会返回所有提及所需产品的项目,只会返回那些在'association_chain'数组的第一个位置提及它的项目。
如果你想这样做,那么你需要一个索引:
db.items.ensureIndex({"association_chain.0.name":1},{background:1})
2)如果您正在寻找特定产品,但您不确定它出现在association_chain的哪个位置,请执行以下操作:
使用MongoDB shell,您可以使用'。'访问嵌套结构中的任何哈希键。点操作员!请注意,这与该密钥嵌套在记录中的深度无关(不是很酷吗?)
你可以在这样的嵌入式哈希数组上进行查找:
db.items.find("association_chain.name":"something")
这将返回集合中包含association_array中任何位置提到的所需产品的所有记录。
如果你想这样做,你应该确保你有一个索引:
db.items.ensureIndex({"association_chain.name":1},{background: 1})
请参阅此页面上的“点符号”:http://docs.mongodb.org/manual/core/document/
答案 2 :(得分:1)
您可以使用聚合框架执行此操作。在mongo shell中运行一个查询来展开文档,这样你就可以在每个数组元素中有一个文档(在其他字段中有重复的数据),然后按id和你想要包含的任何其他字段分组,再加上运算符$ first的数组。然后只需要包含$ match运算符按名称或mongoid进行过滤。
以下是第一个产品名称匹配的查询:
db.foo.aggregate([
{ $unwind:"$association_chain"
},
{
$group : {
"_id" : {
"_id" : "$_id",
"other" : "$other"
},
"association_chain" : {
$first : "$association_chain"
}
}
},
{ $match:{ "association_chain.name":"Product"}
}
])
以下是如何通过mongoid查询第一个产品:
db.foo.aggregate([
{ $unwind:"$association_chain"
},
{
$group : {
"_id" : {
"_id" : "$_id",
"other" : "$other"
},
"association_chain" : {
$first : "$association_chain"
}
}
},
{ $match:{ "association_chain.id":ObjectId("4e1e2cdd9a86652647000007")}
}
])