MongoDB填充数据未包含在查询结果中

时间:2018-01-16 03:32:27

标签: javascript mongodb

假设我有一个包含这些数据的集合:

{"date" : ISODate("2018-01-01T00:00:00Z"), "count" : 3 }
{"date" : ISODate("2018-01-02T00:00:00Z"), "count" : 0 }
{"date" : ISODate("2018-01-03T00:00:00Z"), "count" : 0 }
{"date" : ISODate("2018-01-04T00:00:00Z"), "count" : 5 }
{"date" : ISODate("2018-01-05T00:00:00Z"), "count" : 0 }

我应该使用哪些mongodb函数,以便生成一个查询结果:

{{1}}

基本上,我想迭代日期范围,如果给定日期不在集合中,我只输出'count':0。

我可以通过检索文档并使用javascript代码来填充结果中没有的数据,但我只想知道是否可以通过mongodb查询来实现这一点。

谢谢!

1 个答案:

答案 0 :(得分:2)

可以通过DateTime生成一个范围并自我查找

步骤

  1. $range - 动态查找最小和最大日期,必要时进行硬编码
  2. $group - 生成$project,基于min& max,如果需要,还需要硬编码
  3. $range - 展开文档范围
  4. $unwind - 按生成的号码生成日期
  5. $project - 根据日期自行加入收藏
  6. $lookup - 如果匹配找到返回计数,则为0.如果mongo版本小于3.6,则将$project更改为$ifNull
  7. 聚合管道

    $cond

    集合

    db.t.aggregate(
        [   
            {
                $group : { _id : null, startDate : { "$min" : "$date" }, endDate : { "$max" : "$date" }} 
            },
            {
                $project : { _id : 0 , startDate : 1,  genNo : { $range : [ { $add : [ {"$dayOfMonth" : "$startDate"}, -1 ] }, { $add : [ {"$dayOfMonth" : "$endDate"} , 1 ] } ] } }
            },
            {
                $unwind : "$genNo"
            },
            {
                $project : { genDate : { $add : [ "$startDate", { $multiply : [ "$genNo" , 86400000 ] } ] } }
            },
            {
                $lookup : {
                    from : "t",
                    localField : "genDate",
                    foreignField : "date",
                    as : "out"
                }
            },
            {
                $project : { date : "$genDate", count : { $ifNull : [ { $arrayElemAt : ["$out.count", 0 ] }, 0 ] } }
            }
        ]
    )
    

    汇总结果

    > db.t.find()
    { "_id" : ObjectId("5a5d78d5423b9839ce07bd77"), "date" : ISODate("2018-01-01T00:00:00Z"), "count" : 3 }
    { "_id" : ObjectId("5a5d78d5423b9839ce07bd78"), "date" : ISODate("2018-01-04T00:00:00Z"), "count" : 5 }
    >