- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我对 sql 查询相当擅长,但我似乎无法理解分组和获取 mongo db 文档的总和,
与 this请记住,我有一个工作模型,其架构如下:
{
name: {
type: String,
required: true
},
info: String,
active: {
type: Boolean,
default: true
},
all_service: [
price: {
type: Number,
min: 0,
required: true
},
all_sub_item: [{
name: String,
price:{ // << -- this is the price I want to calculate
type: Number,
min: 0
},
owner: {
user_id: { // <<-- here is the filter I want to put
type: Schema.Types.ObjectId,
required: true
},
name: String,
...
}
}]
],
date_create: {
type: Date,
default : Date.now
},
date_update: {
type: Date,
default : Date.now
}
}
price
列,其中
owner
存在,我在下面尝试过但没有运气
Job.aggregate(
[
{
$group: {
_id: {}, // not sure what to put here
amount: { $sum: '$all_service.all_sub_item.price' }
},
$match: {'not sure how to limit the user': given_user_id}
}
],
//{ $project: { _id: 1, expense: 1 }}, // you can only project fields from 'group'
function(err, summary) {
console.log(err);
console.log(summary);
}
);
最佳答案
底漆
正如前面正确指出的,将聚合“管道”视为“管道”|
确实有帮助。来自 Unix 和其他系统 shell 的操作符。一个“阶段”将输入提供给“下一个”阶段,依此类推。
这里需要注意的是,您有“嵌套”数组,一个数组在另一个数组中,如果您不小心,这可能会对您的预期结果产生巨大影响。
您的文档由顶层的“all_service”数组组成。大概这里经常有“多个”条目,所有条目都包含您的“价格”属性以及“all_sub_item”。那么当然“all_sub_item”本身就是一个数组,也包含它自己的许多项目。
您可以将这些数组视为 SQL 中表之间的“关系”,在每种情况下都是“一对多”。但是数据采用“预连接”形式,您可以在其中一次获取所有数据而无需执行连接。这么多你应该已经熟悉了。
但是,当您想要“聚合”跨文档时,您需要通过“定义”“连接”以与在 SQL 中大致相同的方式对其进行“反规范化”。这是将数据“转换”为适合聚合的非规范化状态。
所以同样的可视化适用。主文档的条目按子文档的数量进行复制,“加入”到“内部子文档”将相应地复制主文档和初始“子文档”。简而言之,这是:
{
"a": 1,
"b": [
{
"c": 1,
"d": [
{ "e": 1 }, { "e": 2 }
]
},
{
"c": 2,
"d": [
{ "e": 1 }, { "e": 2 }
]
}
]
}
{ "a" : 1, "b" : { "c" : 1, "d" : { "e" : 1 } } }
{ "a" : 1, "b" : { "c" : 1, "d" : { "e" : 2 } } }
{ "a" : 1, "b" : { "c" : 2, "d" : { "e" : 1 } } }
{ "a" : 1, "b" : { "c" : 2, "d" : { "e" : 2 } } }
$unwind
,并且由于有多个数组,因此您需要
$unwind
在继续任何处理之前:
db.collection.aggregate([
{ "$unwind": "$b" },
{ "$unwind": "$b.d" }
])
{ "a" : 1, "b" : { "c" : 1, "d" : [ { "e" : 1 }, { "e" : 2 } ] } }
{ "a" : 1, "b" : { "c" : 2, "d" : [ { "e" : 1 }, { "e" : 2 } ] } }
$unwind
之类的操作时。 ,那么您不希望对甚至与您的目标数据不匹配的文档执行此操作。
$match
在“管道”的开头,你还
$match
处理完“所有”后
$unwind
语句,直到您希望匹配的元素的级别。
Job.aggregate(
[
// Match to filter possible "documents"
{ "$match": {
"all_service.all_sub_item.owner": given_user_id
}},
// De-normalize arrays
{ "$unwind": "$all_service" },
{ "$unwind": "$all_service.all_subitem" },
// Match again to filter the array elements
{ "$match": {
"all_service.all_sub_item.owner": given_user_id
}},
// Group on the "_id" for the "key" you want, or "null" for all
{ "$group": {
"_id": null,
"total": { "$sum": "$all_service.all_sub_item.price" }
}}
],
function(err,results) {
}
)
$redact
运算符(operator)。在这种情况下,这可用于在使用
$unwind
处理之前“预过滤”数组内容。 :
Job.aggregate(
[
// Match to filter possible "documents"
{ "$match": {
"all_service.all_sub_item.owner": given_user_id
}},
// Filter arrays for matches in document
{ "$redact": {
"$cond": {
"if": {
"$eq": [
{ "$ifNull": [ "$owner", given_user_id ] },
given_user_id
]
},
"then": "$$DESCEND",
"else": "$$PRUNE"
}
}},
// De-normalize arrays
{ "$unwind": "$all_service" },
{ "$unwind": "$all_service.all_subitem" },
// Group on the "_id" for the "key" you want, or "null" for all
{ "$group": {
"_id": null,
"total": { "$sum": "$all_service.all_sub_item.price" }
}}
],
function(err,results) {
}
)
$unwind
之前有效地删除任何“不匹配”的数组元素。 .这可以加快速度,因为不匹配的项目不需要“解开”。然而,有一个“捕获”,因为如果由于某种原因“所有者”根本不存在于数组元素上,那么此处所需的逻辑会将其视为另一个“匹配”。您可以随时
$match
再次确定,但仍然有更有效的方法来做到这一点:
Job.aggregate(
[
// Match to filter possible "documents"
{ "$match": {
"all_service.all_sub_item.owner": given_user_id
}},
// Filter arrays for matches in document
{ "$project": {
"all_items": {
"$setDifference": [
{ "$map": {
"input": "$all_service",
"as": "A",
"in": {
"$setDifference": [
{ "$map": {
"input": "$$A.all_sub_item",
"as": "B",
"in": {
"$cond": {
"if": { "$eq": [ "$$B.owner", given_user_id ] },
"then": "$$B",
"else": false
}
}
}},
false
]
}
}},
[[]]
]
}
}},
// De-normalize the "two" level array. "Double" $unwind
{ "$unwind": "$all_items" },
{ "$unwind": "$all_items" },
// Group on the "_id" for the "key" you want, or "null" for all
{ "$group": {
"_id": null,
"total": { "$sum": "$all_items.price" }
}}
],
function(err,results) {
}
)
$redact
相比,该过程“大幅”减少了两个数组中项目的大小。 .
$map
运算符将数组的每个元素处理为“in”中的给定语句。在这种情况下,每个“外部”数组元素都被发送到另一个
$map
处理“内部”元素。
$cond
执行逻辑测试因此,如果满足“条件”,则返回“内部”数组元素,否则返回
false
值被返回。
$setDifference
用于过滤掉任何
false
返回的值。或者在“外部”情况下,由所有
false
产生的任何“空白”数组从“内部”过滤的值,那里没有匹配项。这仅留下匹配的项目,包含在“双”数组中,例如:
[[{ "_id": 1, "price": 1, "owner": "b" },{..}],[{..},{..}]]
_id
默认情况下使用 Mongoose (这是您保留它的一个很好的理由),那么除了删除不匹配的值之外,每个项目都是“不同的”并且不受“设置”运算符的影响。
$unwind
“两次”将这些转换为自己文档中的普通对象,适合聚合。
关于node.js - Mongoose 聚合 "$sum"子文档中的行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31437026/
我有这个 html 代码: HELLO WORLD! X V HELLO WORLD! X V 我想按 X(类关闭)将父 div 的高度更改为 20px 并显示 V(类打开),但在每个 d
在会计应用程序的许多不同实现中,有两种主要的数据库设计方法来保存日志和分类帐数据。 只保留 Journal 信息,然后 Ledger 只是 Journal 的一个 View (因为 journal 总
我想在另一个子里面有一个子, sub a { sub b { } } 我想为每次调用 sub b 创建一个新的 sub a 实例。有没有办法在 Perl 中做到这一点? 当我运行上面的
我有一些代码正在查找重复项并突出显示单元格: Private Sub cmdDups_Click() Dim Rng As Range Dim cel As Range Set Rng = ThisW
可能有一个简单的解决方案,但我很难过。 我有一个包含一个 ID 字段的主表。在两个可能的字段中有一个具有该 ID 的子表。想象一个由选手 A 和选手 B 组成的 double 队。Master 表将有
假设我有一个包含对象的数组: [ { "id": "5a97e047f826a0111b754beb", "name": "Hogwarts", "parentId": "
我正在尝试对 MySQL 数据库表执行一对父/子模型的批量插入,但似乎无法使用标准的 ActiveRecord 功能来完成。所以,我尝试了 activerecord-import gem,但它也不支持
我有一个带有多个子类的父抽象类。最终,我希望通过 GUI 中的进度条显示子类中完成的进度。 我目前所做的,我意识到这是行不通的,是在父类中声明为每个子类将覆盖的虚拟方法的事件方法定义。所以像: pub
是否可以通过键数组在对象中设置变量?例如我有这个对象: var obj = {'outer': {'inner': 'value'} }; 并希望设置由键数组选择的值: var keys = ['ou
我有一个名为 companies 的 MySQL 表,如下所示: +---------+-----------+-----------+ | id_comp | comp_name | id_pare
我正在尝试使用 sublime text 在 sublime text 上的 ionic 上打开我的第一个应用程序。它给了我一个“找不到命令”的错误。如何修复? 我试过这些命令: sudo rm -r
不好意思问,但我正在使用 webapp2,我正在设计一个解决方案,以便更容易定义路由 based on this google webapp2 route function .但这完全取决于能够在子级
我有代表树的数字字符串(我不知道是否有官方名称): 012323301212 上面的例子代表了 2 棵树。根用 0 表示。根的直接子代为“1”,“1”的直接子代为“2”,依此类推。我需要将它们分组到由
是否可以在当前 Activity 之上添加 Activity 。例如,假设我单击一个按钮,然后它将第二个 Activity 添加到当前 Activity 。而第二个 Activity 只覆盖了我当前
我很难思考如何为子资源建模。 以作者的书籍为例。你可以有 N 本书,每本书只有一位作者。 /books GET /books POST /books/id PUT /books/id DELETE 到
有人可以向我解释以下内容(python 2.7) 来自已解析文件的两个字符串数字: '410.9''410.9 '(注意尾随空格) A_LIST = ['410.9 '] '410.9' in '41
背景 在 PowerShell 中构建 hash table 是很常见的通过特定属性快速访问对象,例如以 LastName 为基础建立索引: $List = ConvertFrom-Csv @' I
我真的很难弄清楚如何调用嵌套 Polymer Web 组件的函数。 这是标记: rise-distribution组件有 canPlay我想从 rise-playlist
我写了一个小工具转储(以 dot 格式)一个项目的依赖关系图,其中所有位于同一目录中的文件都聚集在一个集群中。当我尝试生成包含相应图形的 pdf 时,dot开始哭: 命令 dot -Tpdf trim
给定一个 CODE ref,是否可以: 访问该 CODE ref 的解析树 通过指定 CODE ref 的解析树来创建一个新的 CODE ref,该解析树可以包含在 1 中返回的解析树的元素 通常我们
我是一名优秀的程序员,十分优秀!