我有一个包含以下文档的集合:
{
_id: "1234",
_class: "com.acme.classA",
a_collection: [
{
otherdata: 'somedata',
type: 'a'
},
{
otherdata: 'bar',
type: 'a'
},
{
otherdata: 'foo',
type: 'b'
}
],
lastChange: ISODate("2014-08-17T22:25:48.918Z")
}
我想通过id和子数组的子集找到所有文档。例如,我想找到ID为“1234”的所有文档,a_collection.type为“a”,给出了这个结果:
{
_id: "1234",
_class: "com.acme.classA",
a_collection: [
{
otherdata: 'somedata',
type: 'a'
},
{
otherdata: 'bar',
type: 'a'
}
],
lastChange: ISODate("2014-08-17T22:25:48.918Z")
}
我试过这个:
db.collection_name.aggregate({
$match: {
'a_collection.type': 'a'
}
},
{
$unwind: "$a_collection"
},
{
$match: {
"a_collection.type": 'a'
}
},
{
$group: {
_id: "$_id",
a_collection: {
$addToSet: "$a_collection"
},
}
}).pretty()
但这不会返回其他属性(例如'lastChange') 这样做的正确方法是什么?
答案 0 :(得分:0)
您使用的是PHP吗?
这是你获得“文字”的唯一方法吗?
也许你可以重写它就像一个JSON元素。
类似的东西:
{
"_id": "1234",
"_class": "com.acme.classA",
"a_collection": [
{
"otherdata": "somedata",
"type": "a"
},
{
"otherdata": "bar",
"type": "a"
},
{
"otherdata": "foo",
"type": "b"
}
]
}
然后你可以使用PHP的json_decode()函数创建一个数组,然后你可以搜索并只返回所需的数据。
编辑:我读了读错。你在寻找像这样的功能吗?
db.inventory.find( {
$or: [ { _id: "1234" }, { 'a_collection.type': 'a' }]
} )
[Here] [1]我找到了代码;)[1]:http://docs.mongodb.org/manual/tutorial/query-documents/
答案 1 :(得分:0)
这是正确的查询:
db.collection_name.aggregate({
$match: {
'a_collection.type': 'a'
}
},
{
$unwind: "$a_collection"
},
{
$match: {
"a_collection.type": 'a'
}
},
{
$group: {
_id: "$_id",
a_collection: {
$addToSet: "$a_collection"
},
lastChange : { $first : "$lastChange" }
}
}).pretty()
答案 2 :(得分:0)
您想要的查询(以及您的管道)有些奇怪。首先,_id
是一个保留字段,上面有唯一索引。使用_id = "1234"
查找所有文档的结果只能是0或1个文档。其次,要为数组a_collection.type = "a"
的某个元素查找a_collection
的文档,您不需要聚合框架。您只需要查找查询:
> db.test.find({ "a_collection.type" : "a" })
因此,这里的所有工作似乎都是将一个文档的子数组缩小到只有a_collection.type = "a"
的元素。如果您执行的大部分操作是将它们分开并删除一些以查找结果集,那么为什么在同一文档中包含这些对象?使用a_collection.type = "a"
只收集数组元素有多常见,多么真实?也许您希望以不同的方式对数据建模,以便像
> db.test.find({ <some condition>, "a_collection.type" : "a" })
返回正确的文件。我不能说如何使用给定的信息做到最好,但我可以说你当前的方法强烈建议需要修改(如果你包含更多信息或发布一个新问题,我很乐意帮助提出建议)
答案 3 :(得分:0)
我同意你自己提交的答案,但是对于MongoDB 2.6及更高版本中的答案,有一种更好的方法可以使用$map
和$setDifference
。哪个都在该版本中引入。但是在可行的情况下,这种方法要快得多:
db.collection.aggregate([
{ "$match": { "a_collection.type": "a" } },
{ "$project": {
"$setDifference": [
{ "$map": [
"input": "$a_collection",
"as": "el",
"in": {
"$cond": [
{ "$eq": [ "$$el.type", "a" ] },
"$$el",
false
]
}
]},
[false]
]
}}
])
因此,没有“组”或初始“放松”,这两个都可能是昂贵的选项,以及 $match
阶段。所以MongoDB 2.6做得更好。