我有一个收藏:
{ "name" : "A", "value" : 1, "date" : ISODate("2014-01-01T00:00:00.000Z") }
{ "name" : "B", "value" : 7, "date" : ISODate("2014-01-01T00:00:00.000Z") }
{ "name" : "A", "value" : 3, "date" : ISODate("2014-01-02T00:00:00.000Z") }
{ "name" : "B", "value" : 8, "date" : ISODate("2014-01-02T00:00:00.000Z") }
{ "name" : "B", "value" : 8, "date" : ISODate("2014-01-03T00:00:00.000Z") }
{ "name" : "A", "value" : 5, "date" : ISODate("2014-01-04T00:00:00.000Z") }
{ "name" : "A", "value" : 4, "date" : ISODate("2014-01-05T00:00:00.000Z") }
2014 年 1 月 3 日的 A 文件不可用。当我在 A 上执行查找/聚合时,我希望该文档以默认值(或更好,值与前一个日期相同)出现在我的结果集中。例如:
{ "name" : "A", "value" : 1, "date" : ISODate("2014-01-01T00:00:00.000Z") }
{ "name" : "A", "value" : 3, "date" : ISODate("2014-01-02T00:00:00.000Z") }
{ "name" : "A", "value" : 3 (or default value -1), "date" : ISODate("2014-01-03T00:00:00.000Z") }
{ "name" : "A", "value" : 5, "date" : ISODate("2014-01-04T00:00:00.000Z") }
{ "name" : "A", "value" : 4, "date" : ISODate("2014-01-05T00:00:00.000Z") }
如何做到这一点?
最佳答案
为了能够在聚合框架中执行此操作,您需要做的一件事是您希望报告涵盖的日期数组。例如,对于您显示的输入,您可能有一个数组:
days = [ ISODate("2014-01-01T00:00:00Z"), ISODate("2014-01-02T00:00:00Z"),
ISODate("2014-01-03T00:00:00Z"), ISODate("2014-01-04T00:00:00Z"),
ISODate("2014-01-05T00:00:00Z"), ISODate("2014-01-06T00:00:00Z") ];
表示您希望这六天中的每一天都有代表。
这是您要运行的聚合:
db.coll.aggregate( [
{$group : {_id:{name:"$name",date:"$date"},value:{$sum:"$value"}}},
{$group : {_id:"$_id.name", days:{$addToSet:"$_id.date"},docs:{$push:"$$ROOT"}}},
{$project : {missingDays:{$setDifference:[days,"$days"]},docs:1}},
{$unwind : "$missingDays"},
{$unwind : "$docs"},
{$group : {
_id:"$_id",
days:{$addToSet:{date:"$docs._id.date",value:"$docs.value"}},
missingDays:{$addToSet:{date:"$missingDays",value:{$literal:0}}}
} },
{$project : {_id:0, name:"$_id", date:{$setUnion:["$days","$missingDays"]}}},
{$unwind : "$date"},
{$sort : {date:1,name:1}}
] )
在您的示例输入中,如上定义的天数输出:
{ "name" : "A", "date" : { "date" : ISODate("2014-01-01T00:00:00Z"), "value" : 1 } }
{ "name" : "A", "date" : { "date" : ISODate("2014-01-02T00:00:00Z"), "value" : 3 } }
{ "name" : "A", "date" : { "date" : ISODate("2014-01-03T00:00:00Z"), "value" : 0 } }
{ "name" : "A", "date" : { "date" : ISODate("2014-01-04T00:00:00Z"), "value" : 5 } }
{ "name" : "A", "date" : { "date" : ISODate("2014-01-05T00:00:00Z"), "value" : 4 } }
{ "name" : "A", "date" : { "date" : ISODate("2014-01-06T00:00:00Z"), "value" : 0 } }
{ "name" : "B", "date" : { "date" : ISODate("2014-01-01T00:00:00Z"), "value" : 7 } }
{ "name" : "B", "date" : { "date" : ISODate("2014-01-02T00:00:00Z"), "value" : 8 } }
{ "name" : "B", "date" : { "date" : ISODate("2014-01-03T00:00:00Z"), "value" : 8 } }
{ "name" : "B", "date" : { "date" : ISODate("2014-01-04T00:00:00Z"), "value" : 0 } }
{ "name" : "B", "date" : { "date" : ISODate("2014-01-05T00:00:00Z"), "value" : 0 } }
{ "name" : "B", "date" : { "date" : ISODate("2014-01-06T00:00:00Z"), "value" : 0 } }
在您的情况下,第一个小组阶段可能不是必需的 - 如果有多个文档具有相同的名称和日期,那么您需要为它们添加值。第二个 $group 和 $project 阶段计算出每个名字存在的天数和你想要覆盖的天数数组之间的差异,创建 missingDays 它将在下一个 中获得值 0 $group 阶段。该小组赛阶段为每个 name 创建一个包含数据的日期数组和一个没有数据的缺失日期数组。它以 say 的方式构造它们,以便接下来的 $project 阶段可以使用 $setUnion 运算符创建它们的并集。之后,剩下的就是$unwind 日期数组并按照您想要的方式对其进行排序。
关于mongodb - 查找/聚合后用默认值填充文档,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24752090/
我正在使用的第三方API的文档状态:"[O]urAPIonlyacceptspaddedBase64encodedstrings."什么是“填充的Base64编码字符串”以及如何在Ruby中生成它们。下面的代码是我第一次尝试创建转换为Base64的JSON格式数据。xa=Base64.encode64(a.to_json) 最佳答案 他们说的padding其实就是Base64本身的一部分。它是末尾的“=”和“==”。Base64将3个字节的数据包编码为4个编码字符。所以如果你的输入数据有长度n和n%3=1=>"=="末尾用于填充n%
这是在Ruby中设置默认值的常用方法:classQuietByDefaultdefinitialize(opts={})@verbose=opts[:verbose]endend这是一个容易落入的陷阱:classVerboseNoMatterWhatdefinitialize(opts={})@verbose=opts[:verbose]||trueendend正确的做法是:classVerboseByDefaultdefinitialize(opts={})@verbose=opts.include?(:verbose)?opts[:verbose]:trueendend编写Verb
我想设置一个默认日期,例如实际日期,我该如何设置?还有如何在组合框中设置默认值顺便问一下,date_field_tag和date_field之间有什么区别? 最佳答案 试试这个:将默认日期作为第二个参数传递。youcorrectlysetthedefaultvalueofcomboboxasshowninyourquestion. 关于ruby-on-rails-date_field_tag,如何设置默认日期?[rails上的ruby],我们在StackOverflow上找到一个类似的问
两者都可以defsetup(options={})options.reverse_merge:size=>25,:velocity=>10end和defsetup(options={}){:size=>25,:velocity=>10}.merge(options)end在方法的参数中分配默认值。问题是:哪个更好?您更愿意使用哪一个?在性能、代码可读性或其他方面有什么不同吗?编辑:我无意中添加了bang(!)...并不是要询问nobang方法与bang方法之间的区别 最佳答案 我倾向于使用reverse_merge方法:option
我刚刚被困在这个问题上一段时间了。以这个基地为例:moduleTopclassTestendmoduleFooendend稍后,我可以通过这样做在Foo中定义扩展Test的类:moduleTopmoduleFooclassSomeTest但是,如果我尝试通过使用::指定模块来最小化缩进:moduleTop::FooclassFailure这失败了:NameError:uninitializedconstantTop::Foo::Test这是一个错误,还是仅仅是Ruby解析变量名的方式的逻辑结果? 最佳答案 Isthisabug,or
我有一个驼峰式字符串,例如:JustAString。我想按照以下规则形成长度为4的字符串:抓取所有大写字母;如果超过4个大写字母,只保留前4个;如果少于4个大写字母,则将最后大写字母后的字母大写并添加字母,直到长度变为4。以下是可能发生的3种情况:ThisIsMyString将产生TIMS(大写字母);ThisIsOneVeryLongString将产生TIOV(前4个大写字母);MyString将生成MSTR(大写字母+tr大写)。我设法用这个片段解决了前两种情况:str.scan(/[A-Z]/).first(4).join但是,我不太确定如何最好地修改上面的代码片段以处理最后一种
我正在尝试解析一个CSV文件并使用SQL命令自动为其创建一个表。CSV中的第一行给出了列标题。但我需要推断每个列的类型。Ruby中是否有任何函数可以找到每个字段中内容的类型。例如,CSV行:"12012","Test","1233.22","12:21:22","10/10/2009"应该产生像这样的类型['integer','string','float','time','date']谢谢! 最佳答案 require'time'defto_something(str)if(num=Integer(str)rescueFloat(s
matlab打开matlab,用最简单的imread方法读取一个图像clcclearimg_h=imread('hua.jpg');返回一个数组(矩阵),往往是a*b*cunit8类型解释一下这个三维数组的意思,行数、数和层数,unit8:指数据类型,无符号八位整形,可理解为0~2^8的数三个层数分别代表RGB三个通道图像rgb最常用的是24-位实现方法,即RGB每个通道有256色阶(2^8)。基于这样的24-位RGB模型的色彩空间可以表现256×256×256≈1670万色当imshow传入了一个二维数组,它将以灰度方式绘制;可以把图像拆分为rgb三层,可以以灰度的方式观察它figure(1
路由有如下代码:resources:orders,only:[:create],defaults:{format:'json'}resources:users,only:[:create,:update],defaults:{format:'json'}resources:delivery_types,only:[:index],defaults:{format:'json'}resources:time_corrections,only:[:index],defaults:{format:'json'}是否可以使用1个字符串为所有资源设置默认格式,每行不带“默认值”散列?谢谢。
我是ruby的新手,正在配置IRB。我喜欢pretty-print(需要'pp'),但总是输入pp来漂亮地打印它似乎很麻烦。我想做的是默认情况下让它漂亮地打印出来,所以如果我有一个var,比如说,'myvar',然后键入myvar,它会自动调用pretty_inspect而不是常规检查。我从哪里开始?理想情况下,我将能够向我的.irbrc文件添加一个自动调用的方法。有什么想法吗?谢谢! 最佳答案 irb中默认pretty-print对象正是hirb被迫去做。Theseposts解释hirb如何将几乎所有内容转换为ascii表。虽