- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我有一个 MongoDB 集合,其结构(简化)如下:
[
{
"name" : "name1",
"instances" : [
{
"value" : 1,
"score" : 2,
"date" : ISODate("2015-03-04T00:00:00.000Z")
},
{
"value" : 2,
"score" : 5,
"date" : ISODate("2015-04-01T00:00:00.000Z")
},
{
"value" : 2.5,
"score" : 9,
"date" : ISODate("2015-03-05T00:00:00.000Z")
}
]
},
{
"name" : "name2",
"instances" : [
{
"value" : 6,
"score" : 3,
"date" : ISODate("2015-03-05T00:00:00.000Z")
},
{
"value" : 1,
"score" : 6,
"date" : ISODate("2015-03-04T00:00:00.000Z")
},
{
"value" : 3.7,
"score" : 5.2,
"date" : ISODate("2015-02-04T00:00:00.000Z")
}
]
},
{
"name" : "name3",
"instances" : [
{
"value" : 6,
"score" : 3,
"date" : ISODate("2015-03-05T00:00:00.000Z")
},
{
"value" : 1,
"score" : 6,
"date" : ISODate("2015-03-04T00:00:00.000Z")
},
{
"value" : 3.7,
"score" : 5.2,
"date" : ISODate("2015-02-04T00:00:00.000Z")
}
]
}
]
目前我有一个 aggregate
查询,它在给定日期之前从每个文档中提取单个实例:
db.myCollection.aggregate([
{$unwind: "$instances"},
{$sort: {'instances.date': -1}},
{$match: {'instances.date': {$lte: <givenDate>}}},
{$project: {name: 1, _id: 0, date: "$instances.date", value: "$instances.value", score: "$instances.score"}},
{$group: {_id: "$name", name: {$first: "$name"}, date: {$first: "$date"},
value: {$first: "$value"}, score: {$first: "$score"}}}
])
此查询工作得很好,对于给定的日期,将从每个文档返回最新的(即恰好或早于给定日期的)实例。
当给定日期早于最早实例时,我的问题就开始了。例如,如果我给定的日期是 2015 年 3 月 2 日,我将不会从 name1
获取任何实例。在这种情况下,我想检索文档中可用的最早实例。
显然,我可以将此任务拆分为两个不同的查询并合并结果,但如果可能的话,我希望在单个数据库查询中实现此目标。
有什么想法吗?
最佳答案
管道
试试这个管道,然后让我们一步步来:
[
{$unwind: "$instances"},
{$project: {
_id: 0,
name: 1,
date: '$instances.date',
matches: {
$cond: [
{$lte: ['$instances.date', new Date(<YOUR DATE>)]},
1,
0
]
},
score: '$instances.score',
value: '$instances.value'
}
},
{$group: {
_id: '$name',
instances: {
$push: {
date: '$date',
score: '$score',
value: '$value',
matches: '$matches'
}
},
hasMatches: {$sum: '$matches'}
}
},
{$unwind: "$instances"},
{$project: {
_id: 0,
name: '$_id',
date: '$instances.date',
hasMatches: '$hasMatches',
matches: '$instances.matches',
score: '$instances.score',
value: '$instances.value'
}
},
{$sort: {'name': 1, 'matches': -1, 'date': -1}},
{$group: {
_id: {name: '$name', hasMatches: '$hasMatches'},
last_date: {$last: '$date'},
last_score: {$last: '$score'},
last_value: {$last: '$value'},
first_date: {$first: '$date'},
first_score: {$first: '$score'},
first_value: {$first: '$value'}}
},
{$project: {
name: '$_id.name',
date: {$cond: ['$_id.hasMatches', '$first_date', '$last_date']},
score: {$cond: ['$_id.hasMatches', '$first_score', '$last_score']},
value: {$cond: ['$_id.hasMatches', '$first_value', '$last_value']},
_id: 0}
}
]
解释
第一个$unwind
和$project
阶段很简单明了,我只加了一个matches
字段,表示unwounded文档是否匹配你的标准。
然后我们$group
回溯文档,同时$sum
将matches
字段添加到新的hasMatches
。生成的文档现在包含 hasMatches
字段,该字段指示 instances
数组是否包含至少一个符合您的条件的元素。
然后,我们再次$unwind
和$project
,然后再次$group
,保留hasMatches
字段并为 date
、value
和 score
存储 $first
和 $last
值> 进行进一步处理。
现在情况如下:
如果初始数组中至少有一个元素符合条件,则在排序结果中它会作为其组中的第一个文档出现。
如果初始数组中没有符合条件的元素,则在排序结果中,日期最早的元素出现在最后 文档在其组中。
因此,由于我们有指示上述条件的 hasMatches
字段,以及 first_X
和 last_X
值,我们可以轻松地根据 hasMatches
值选择其中之一。因此,最后一个 $project
阶段就是这样做的。
结果
以下是您在评论中提到的日期的结果:
'2015-03-04':
{ "name" : "name3", "date" : ISODate("2015-03-04T00:00:00Z"), "score" : 6, "value" : 1 }
{ "name" : "name2", "date" : ISODate("2015-03-04T00:00:00Z"), "score" : 6, "value" : 1 }
{ "name" : "name1", "date" : ISODate("2015-03-04T00:00:00Z"), "score" : 2, "value" : 1 }
'2015-03-02':
{ "name" : "name3", "date" : ISODate("2015-02-04T00:00:00Z"), "score" : 5.2, "value" : 3.7 }
{ "name" : "name2", "date" : ISODate("2015-02-04T00:00:00Z"), "score" : 5.2, "value" : 3.7 }
{ "name" : "name1", "date" : ISODate("2015-03-04T00:00:00Z"), "score" : 2, "value" : 1 }
关于MongoDB 聚合 - 使用 lte 匹配并回退到 gte,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30477196/
使用sed和/或awk,仅在行包含字符串“ foo”并且行之前和之后的行分别包含字符串“ bar”和“ baz”时,我才希望删除行。 因此,对于此输入: blah blah foo blah bar
例如: S1: "some filename contains few words.txt" S2:“一些文件名包含几个单词 - draft.txt” S3:“一些文件名包含几个单词 - 另一个 dr
我正在尝试处理一些非常困惑的数据。我需要通过样本 ID 合并两个包含不同类型数据的大数据框。问题是一张表的样本 ID 有许多不同的格式,但大多数都包含用于匹配其 ID 中某处所需的 ID 字符串,例如
我想在匹配特定屏幕尺寸时显示特定图像。在这种情况下,对于 Bootstrap ,我使用 col-xx-## 作为我的选择。但似乎它并没有真正按照我认为应该的方式工作。 基本思路,我想显示一种全屏图像,
出于某种原因,这条规则 RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.*
我想做类似的东西(Nemerle 语法) def something = match(STT) | 1 with st= "Summ" | 2 with st= "AVG" =>
假设这是我的代码 var str="abc=1234587;abc=19855284;abc=1234587;abc=19855284;abc=1234587;abc=19855284;abc=123
我怎样才能得到这个字符串的数字:'(31.5393701, -82.46235569999999)' 我已经在尝试了,但这离解决方案还很远:) text.match(/\((\d+),(\d+)\)/
如何去除输出中的逗号 (,)?有没有更好的方法从字符串或句子中搜索 url。 alert(" http://www.cnn.com df".match(/https?:\/\/([-\w\.]+
a = ('one', 'two') b = ('ten', 'ten') z = [('four', 'five', 'six'), ('one', 'two', 'twenty')] 我正在尝试
我已经编写了以下代码,我希望用它来查找从第 21 列到另一张表中最后一行的值,并根据这张表中 A 列和另一张表中 B 列中的值将它们返回到这张表床单。 当我使用下面的代码时,我得到一个工作表错误。你能
我在以下结构中有两列 A B 1 49 4922039670 我已经能够评估 =LEN(A1)如2 , =LEFT(B1,2)如49 , 和 =LEFT(B1,LEN(A1)
我有一个文件,其中一行可以以 + 开头, -或 * .在其中一些行之间可以有以字母或数字(一般文本)开头的行(也包含这些字符,但不在第 1 列中!)。 知道这一点,设置匹配和突出显示机制的最简单方法是
我有一个数据字段文件,其中可能包含注释,如下所示: id, data, data, data 101 a, b, c 102 d, e, f 103 g, h, i // has to do with
我有以下模式:/^\/(?P.+)$/匹配:/url . 我的问题是它也匹配 /url/page ,如何忽略/在这个正则表达式中? 该模式应该: 模式匹配:/url 模式不匹配:/url/page 提
我有一个非常庞大且复杂的数据集,其中包含许多对公司的观察。公司的一些观察是多余的,我需要制作一个键来将多余的观察映射到一个单独的观察。然而,判断他们是否真的代表同一家公司的唯一方法是通过各种变量的相似
我有以下 XML A B C 我想查找 if not(exists(//Record/subRecord
我制作了一个正则表达式来验证潜在的比特币地址,现在当我单击报价按钮时,我希望根据正则表达式检查表单中输入的值,但它不起作用。 https://jsfiddle.net/arkqdc8a/5/ var
我有一些 MS Word 文档,我已将其全部内容转移到 SQL 表中。 内容包含多个方括号和大括号,例如 [{a} as at [b],] {c,} {d,} etc 我需要进行检查以确保括号平衡/匹
我正在使用 Node.js 从 XML 文件读取数据。但是当我尝试将文件中的数据与文字进行比较时,它不匹配,即使它看起来相同: const parser: xml2js.Parser = new
我是一名优秀的程序员,十分优秀!