- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有很多具有很多属性的文档。在特定的 $match
传递之后,我以一个小节结束。这里简化了:
[
{"name": "foo", "code": "bbb"},
{"name": "foo", "code": "aaa"},
{"name": "foo", "code": "aaa"},
{"name": "foo", "code": "aaa"},
{"name": "bar", "code": "aaa"},
{"name": "bar", "code": "aaa"},
{"name": "bar", "code": "aaa"},
{"name": "baz", "code": "aaa"},
{"name": "baz", "code": "aaa"}
]
我想计算某些属性的出现次数,所以我最终得到这个(简化):
{
"name": {
"foo": 4,
"bar": 3,
"baz": 2
},
"code": {
"bbb": 1,
"aaa": 8
}
}
(或者我之后可以用 Node.js ‘翻译’的接近的东西)
我已经做了一个 $group
阶段来计算其他属性(不同)。理想情况下,我会 $addToSet
并计算类似值被添加到集合中的次数。但我想不通。
或者我正在考虑 $push
来结束这个(简化):
{
"name": ["foo", "foo", "foo", "foo", "bar", "bar", "bar", "baz", "baz"],
"code": ["bbb", "aaa", "aaa", "aaa", "aaa", "aaa", "aaa", "aaa", "aaa", ]
}
但我也不知道如何将其变成(接近于)上述假设结果。
仅对于单个字段,最接近的方法是使用上面的 $push
然后我可以使用 $group
:
"$group": {
"_id": {"_id": "$_id", "name": "$name"},
"nameCount": {"$sum": 1}
}
现在我有 _id.name
和 nameCount
。但是我已经失去了所有以前计算的属性,大约 20 个。
有没有办法做(接近)我想做的事?
Note: Using MongoDB 3.2
最佳答案
对于 MongoDB 3.2,如果您想在返回的文档中将“数据”值作为“键”返回,您几乎只能使用 mapReduce。然而,在某些情况下,您实际上“不需要”MongoDB 为您做那部分工作。但要考虑这些方法:
db.stuff.mapReduce(
function() {
emit(null, {
name: { [this.name]: 1 },
code: { [this.code]: 1 }
})
},
function(key,values) {
let obj = { name: {}, code: {} };
values.forEach(value => {
['name','code'].forEach(key => {
Object.keys(value[key]).forEach(k => {
if (!obj[key].hasOwnProperty(k))
obj[key][k] = 0;
obj[key][k] += value[key][k];
})
})
});
return obj;
},
{ "out": { "inline": 1 } }
)
返回:
{
"_id" : null,
"value" : {
"name" : {
"foo" : 4.0,
"bar" : 3.0,
"baz" : 2.0
},
"code" : {
"bbb" : 1.0,
"aaa" : 8.0
}
}
}
对于 MongoDB 3.4 及更高版本,您可以使用 $arrayToObject
将其 reshape 为“键/值”对象。并且比简单地使用 $push
来制作两个大数组更有效,这在现实世界中几乎肯定会打破 BSON 限制。
这个“或多或少”反射(reflect)了 mapReduce()
操作:
db.stuff.aggregate([
{ "$project": {
"_id": 0,
"data": [
{ "k": "name", "v": { "k": "$name", "count": 1 } },
{ "k": "code", "v": { "k": "$code", "count": 1 } }
]
}},
{ "$unwind": "$data" },
{ "$group": {
"_id": { "k": "$data.k", "v": "$data.v.k" },
"count": { "$sum": "$data.v.count" }
}},
{ "$group": {
"_id": "$_id.k",
"v": { "$push": { "k": "$_id.v", "v": "$count" } }
}},
{ "$group": {
"_id": null,
"data": { "$push": { "k": "$_id", "v": "$v" } }
}},
{ "$replaceRoot": {
"newRoot": {
"$arrayToObject": {
"$map": {
"input": "$data",
"in": {
"k": "$$this.k",
"v": { "$arrayToObject": "$$this.v" }
}
}
}
}
}}
])
它具有相似的输出(不通过应用 $sort
强制对键进行排序):
{
"code" : {
"bbb" : 1.0,
"aaa" : 8.0
},
"name" : {
"baz" : 2.0,
"foo" : 4.0,
"bar" : 3.0
}
}
所以它只是在我们实际使用新功能的最后阶段,到那时为止的输出非常相似,并且很容易在代码中 reshape :
{
"_id" : null,
"data" : [
{
"k" : "code",
"v" : [
{
"k" : "bbb",
"v" : 1.0
},
{
"k" : "aaa",
"v" : 8.0
}
]
},
{
"k" : "name",
"v" : [
{
"k" : "baz",
"v" : 2.0
},
{
"k" : "foo",
"v" : 4.0
},
{
"k" : "bar",
"v" : 3.0
}
]
}
]
}
所以事实上我们可以做到这一点:
db.stuff.aggregate([
{ "$project": {
"_id": 0,
"data": [
{ "k": "name", "v": { "k": "$name", "count": 1 } },
{ "k": "code", "v": { "k": "$code", "count": 1 } }
]
}},
{ "$unwind": "$data" },
{ "$group": {
"_id": { "k": "$data.k", "v": "$data.v.k" },
"count": { "$sum": "$data.v.count" }
}},
{ "$group": {
"_id": "$_id.k",
"v": { "$push": { "k": "$_id.v", "v": "$count" } }
}},
{ "$group": {
"_id": null,
"data": { "$push": { "k": "$_id", "v": "$v" } }
}},
/*
{ "$replaceRoot": {
"newRoot": {
"$arrayToObject": {
"$map": {
"input": "$data",
"in": {
"k": "$$this.k",
"v": { "$arrayToObject": "$$this.v" }
}
}
}
}
}}
*/
]).map( doc =>
doc.data.map( d => ({
k: d.k,
v: d.v.reduce((acc,curr) =>
Object.assign(acc,{ [curr.k]: curr.v })
,{}
)
})).reduce((acc,curr) =>
Object.assign(acc,{ [curr.k]: curr.v })
,{}
)
)
这只是因为聚合框架没有在早期版本的输出中使用“命名键”的功能,所以您通常不需要它们。由于我们实际使用新功能的唯一地方是在“最终”阶段,但我们可以通过简单地在客户端代码中 reshape 最终输出来轻松地做到这一点。
当然,结果是一样的:
[
{
"code" : {
"bbb" : 1.0,
"aaa" : 8.0
},
"name" : {
"baz" : 2.0,
"foo" : 4.0,
"bar" : 3.0
}
}
]
因此,了解您实际需要应用此类转换的确切“位置”的教训会有所帮助。这里是“结束”,因为我们在任何“聚合”阶段都不需要它,因此您只需 reshape 可以从聚合框架本身最佳提供的结果。
如前所述,到目前为止,您的尝试对于小数据可能没问题,但在大多数现实世界的情况下,将集合中的所有项目“推送”到一个文档中而不减少将打破 16MB 的 BSON 限制。
它实际上会停留在下面的地方,然后你可以使用类似这个怪物的东西 $reduce
:
db.stuff.aggregate([
{ "$group": {
"_id": null,
"name": { "$push": "$name" },
"code": { "$push": "$code" }
}},
{ "$replaceRoot": {
"newRoot": {
"$arrayToObject": {
"$map": {
"input": [
{ "k": "name", "v": "$name" },
{ "k": "code", "v": "$code" }
],
"as": "m",
"in": {
"k": "$$m.k",
"v": {
"$arrayToObject": {
"$reduce": {
"input": "$$m.v",
"initialValue": [],
"in": {
"$cond": {
"if": {
"$in": [
"$$this",
{ "$map": {
"input": "$$value",
"as": "v",
"in": "$$v.k"
}}
]
},
"then": {
"$concatArrays": [
{ "$filter": {
"input": "$$value",
"as": "v",
"cond": { "$ne": [ "$$v.k", "$$this" ] }
}},
[{
"k": "$$this",
"v": {
"$sum": [
{ "$arrayElemAt": [
"$$value.v",
{ "$indexOfArray": [ "$$value.k", "$$this" ] }
]},
1
]
}
}]
]
},
"else": {
"$concatArrays": [
"$$value",
[{ "k": "$$this", "v": 1 }]
]
}
}
}
}
}
}
}
}
}
}
}}
])
产生:
{
"name" : {
"foo" : 4.0,
"bar" : 3.0,
"baz" : 2.0
},
"code" : {
"bbb" : 1.0,
"aaa" : 8.0
}
}
或者实际上是客户端代码中的相同缩减过程:
db.stuff.aggregate([
{ "$group": {
"_id": null,
"name": { "$push": "$name" },
"code": { "$push": "$code" }
}},
]).map( doc =>
["name","code"].reduce((acc,curr) =>
Object.assign(
acc,
{ [curr]: doc[curr].reduce((acc,curr) =>
Object.assign(acc,
(acc.hasOwnProperty(curr))
? { [curr]: acc[curr] += 1 }
: { [curr]: 1 }
),{}
)
}
),
{}
)
)
同样的结果:
{
"name" : {
"foo" : 4.0,
"bar" : 3.0,
"baz" : 2.0
},
"code" : {
"bbb" : 1.0,
"aaa" : 8.0
}
}
关于javascript - 计算键值的出现次数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45228173/
你好,我有一张 table : from | to | item | count ------- Jack | Danie| food | 10 Danie| Maria| food | 2 Ja
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 这个问题似乎偏离主题,因为它缺乏足够的信息来诊断问题。 更详细地描述您的问题或 include a mini
我正在尝试解决以下面试问题 Given two arrays firstDay and lastDay representing the intervals in days of possible m
这个问题已经有答案了: Explanation of a output of a C program involving fork() (2 个回答) 已关闭 9 年前。 这是我从我的研究所去年的试卷
如何在 html 页面上重复一个 div X 次,可以说我想设置方差来声明重复次数。重复这个部分 5 次,我假设它是用 JS 的。 black BLUE WHITE strip 我
我目前使用类中的函数将数据插入数据库,如果每行成功插入(从 csv 文件),则会记录一条消息(logMessage 函数),以显示哪一行成功或失败。但是我想要已导入数据库的成功执行的计数。我遇到了一些
这个问题可能看起来非常基础,但我很难弄清楚如何做。我有一个整数,我需要使用 for 循环来循环整数次。 首先,我尝试了—— fn main() { let number = 10; // An
我正在准备 CS 125 期末考试,其中(简要地)介绍了 Big O Notation。 鉴于: Mergesort 的最佳运行时间为 O(N lg(N)),最坏运行时间为 O(N lg (N)) 有
关闭。这个问题需要更多focused .它目前不接受答案。 想改进这个问题吗? 更新问题,使其只关注一个问题 editing this post . 关闭 3 年前。 Improve this qu
我正在构建一个简单的程序来计算骰子实验中数字的频率,但我尝试扩展它并将最大 throw 次数增加到巨大的数字,通过反复试验,我发现最大限制为519253。 使用这个最大值,我也无法创建任何新数组,它会
这是一道面试题 There is an airline company that wants to provide new updates to all of its flight attendant
我正在尝试以一种可以节省我无数小时的繁琐数据输入的方式实现 Excel 自动化。这是我的问题。 我们需要为所有库存打印条形码,其中包括 4,000 种型号,每种型号都有特定数量。 Shopify是我们
我想根据给定的预定义级别(从级别 1 到级别 6)分离代码中的所有内容,现在我的 JSON 读取 $scope.myJson=[{ id: 1, level: 1, name: "any
我创建了一个菜单,它使用一些 CSS 和 jquery 在悬停时显示其子菜单。事情是,如果用户在菜单项上多次悬停,它会有点滑稽。这是网址:http://91.202.168.37/~ibi/ ,这是
假设我对每小时的事件数进行了如下统计: np.random.seed(42) idx = pd.date_range('2017-01-01', '2017-01-14', freq='1H') df
我想确保我正确理解了这个概念: 在 Hadoop 权威指南中指出:“设计文件系统的目标始终是减少与要传输的数据量相比的查找次数。”在此声明中,作者指的是 Hadoop 逻辑 block 的“seeks
我有一个用 C++11 编写的程序,我想计算 std::vector 的 move 和复制(构造和赋值)次数。对象。有办法吗? 最好的问候 最佳答案 否。 std::vector<>的执行没有办法做到
我们组织的帐户空间不足,我们一直在尝试剔除一些较旧的存储库。问题在于一些较旧的存储库可能仍然是事件服务的依赖项(即使它们多年未更新)。 我知道我们可以跟踪克隆,但据我所知,我们看不到直接下载/pull
我是一名优秀的程序员,十分优秀!