$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")}}]
               }
           }})

希望对您有所帮助 :)