$elemMatch 嵌入文档
$elemMatch on embedded documents
这是我正在使用的东西:
{
"_id": ObjectId("53b4402ae1382335c95952d3"),
"created": ISODate("2014-07-02T10:23:54.245Z"),
"modified": ISODate("2011-11-28T10:06:25.186Z"),
"source": [{
"instances": [{
"analyst": "harry",
"date": ISODate("2014-07-02T10:23:54.242Z"),
"reference": "abb32"
},
{
"analyst": "david",
"date": ISODate("2014-07-02T10:33:02.296Z"),
"reference": "can26"
}],
"name": "Apples"
},
{
"instances": [{
"analyst": "critsAPI",
"date": ISODate("2011-11-28T10:06:25.156Z"),
"reference": "z561c"
}],
"name": "Oranges"
}],
"releasability": [],
}
我想要的是每个文档的计数,每个文档在特定范围内(比如一个月)具有 "instances date " 以及特定名称。我用 "elemMatch" 使用了两个查询,不幸的是我没有得到我期望的结果。
这是我尝试使用 elemMatch 和 instances.date:
collection.find(
{
'source':
{
'$elemMatch' : {
'name':'Apples',
'instances.date' : {'$lte' : ISODate("2014-07-30T00:00:00Z") ,
'$gte' : ISODate("2014-07-01T00:00:00Z")}
}
}
}
).count()
这是一个嵌套的 elemMatch :
collection.find(
{
'source':
{
'$elemMatch' : {
'name':'Apples',
'instances': {
'$elemMatch' : {
'date' : {'$lte' : ISODate("2014-07-30T00:00:00Z") ,
'$gte' : ISODate("2014-07-01T00:00:00Z")}
}
}
}
}
}
).count()
提前致谢。
我猜你得到的 count()
是 1,因为 count()
方法 returns 文档的数量,而不是数组元素的数量。
要获得结果 2(基于上述文档),您需要使用聚合框架。
请尝试如下操作:
db.coll1.aggregate([
{$unwind : "$source"},
{$unwind : "$source.instances"},
{$match: {
$and: [
{"source.name" : "Apples"},
{"source.instances.date" : {"$lte" : ISODate("2014-07-30T00:00:00Z")}},
{"source.instances.date" : {"$gte" : ISODate("2014-07-01T00:00:00Z")}}
]
}},
{$project: {
name1: "$source.name",
date1: "$source.instances.date"
}},
{$group : {_id: "$name1", name1: {$sum:1}}}
])
我在 shell 中得到以下内容
{ "result" : [ { "_id" : "Apples", "name1" : 2 } ], "ok" : 1 }
$unwind
将数组分成单独的文档,$match
进行选择,$project
定义结果字段(类似于 SELECT
中的子句 SQL),$group
对条目求和(类似于 SQL 中的“GROUP BY”)
聚合管道中的这些单独步骤按顺序 filters/transforms 文档结果集。
希望对你有帮助
我的想法是使用dot notation to access the elements of an array combine with $and运算符来查询'instances date'范围。
collection.find({
'source' : {
$elemMatch:{
'name': 'Apples',
$and:[ {'instances.date' : {$lte : ISODate("2014-07-30T00:00:00Z")}} ,
{'instances.date' : {$gte : ISODate("2014-07-01T00:00:00Z")}}]
}
}})
希望对您有所帮助 :)
这是我正在使用的东西:
{
"_id": ObjectId("53b4402ae1382335c95952d3"),
"created": ISODate("2014-07-02T10:23:54.245Z"),
"modified": ISODate("2011-11-28T10:06:25.186Z"),
"source": [{
"instances": [{
"analyst": "harry",
"date": ISODate("2014-07-02T10:23:54.242Z"),
"reference": "abb32"
},
{
"analyst": "david",
"date": ISODate("2014-07-02T10:33:02.296Z"),
"reference": "can26"
}],
"name": "Apples"
},
{
"instances": [{
"analyst": "critsAPI",
"date": ISODate("2011-11-28T10:06:25.156Z"),
"reference": "z561c"
}],
"name": "Oranges"
}],
"releasability": [],
}
我想要的是每个文档的计数,每个文档在特定范围内(比如一个月)具有 "instances date " 以及特定名称。我用 "elemMatch" 使用了两个查询,不幸的是我没有得到我期望的结果。 这是我尝试使用 elemMatch 和 instances.date:
collection.find(
{
'source':
{
'$elemMatch' : {
'name':'Apples',
'instances.date' : {'$lte' : ISODate("2014-07-30T00:00:00Z") ,
'$gte' : ISODate("2014-07-01T00:00:00Z")}
}
}
}
).count()
这是一个嵌套的 elemMatch :
collection.find(
{
'source':
{
'$elemMatch' : {
'name':'Apples',
'instances': {
'$elemMatch' : {
'date' : {'$lte' : ISODate("2014-07-30T00:00:00Z") ,
'$gte' : ISODate("2014-07-01T00:00:00Z")}
}
}
}
}
}
).count()
提前致谢。
我猜你得到的 count()
是 1,因为 count()
方法 returns 文档的数量,而不是数组元素的数量。
要获得结果 2(基于上述文档),您需要使用聚合框架。
请尝试如下操作:
db.coll1.aggregate([ {$unwind : "$source"}, {$unwind : "$source.instances"}, {$match: { $and: [ {"source.name" : "Apples"}, {"source.instances.date" : {"$lte" : ISODate("2014-07-30T00:00:00Z")}}, {"source.instances.date" : {"$gte" : ISODate("2014-07-01T00:00:00Z")}} ] }}, {$project: { name1: "$source.name", date1: "$source.instances.date" }}, {$group : {_id: "$name1", name1: {$sum:1}}} ])我在 shell 中得到以下内容
{ "result" : [ { "_id" : "Apples", "name1" : 2 } ], "ok" : 1 }
$unwind
将数组分成单独的文档,$match
进行选择,$project
定义结果字段(类似于 SELECT
中的子句 SQL),$group
对条目求和(类似于 SQL 中的“GROUP BY”)
聚合管道中的这些单独步骤按顺序 filters/transforms 文档结果集。
希望对你有帮助
我的想法是使用dot notation to access the elements of an array combine with $and运算符来查询'instances date'范围。
collection.find({
'source' : {
$elemMatch:{
'name': 'Apples',
$and:[ {'instances.date' : {$lte : ISODate("2014-07-30T00:00:00Z")}} ,
{'instances.date' : {$gte : ISODate("2014-07-01T00:00:00Z")}}]
}
}})
希望对您有所帮助 :)