Node.js MongoDB聚合:在展开操作后对真实文档进行计数?
这是我的模式:Node.js MongoDB聚合:在展开操作后对真实文档进行计数?,node.js,mongodb,mongoose,mongodb-query,aggregation-framework,Node.js,Mongodb,Mongoose,Mongodb Query,Aggregation Framework,这是我的模式: company: String model: String tags: [String] // array of strings 我的问题是: { "$unwind": "$tags" }, { "$group": { "_id": { "company": "$company", "model": "$model", "tag": "$tags" }, "tagCount": { "$sum": 1 },
company: String
model: String
tags: [String] // array of strings
我的问题是:
{ "$unwind": "$tags" },
{ "$group": {
"_id": {
"company": "$company",
"model": "$model",
"tag": "$tags"
},
"tagCount": { "$sum": 1 },
"reviewCount": { "$sum" : 1}
}},
{ "$group": {
"_id": {
"company": "$_id.company",
"model": "$_id.model",
},
"tags": { "$push": { "tag": "$_id.tag", "count": "$tagCount" },
"count": { "$sum": "$reviewCount" }
}}
请注意,我有tagCount
和reviewCount
tagCount
必须显示不同评论中某些型号的标签匹配数。reviewCount
必须显示某些模型的审核次数
但是,reviewCount
当前显示的数字不正确,原因是展开操作
在展开每个文档中的标签
列表后,获取某些型号
文档数量的有效方法是什么?
注意:我也尝试过这样做:
{ "$group": {
"_id": {
"company": "$company",
"model": "$model"
},
"reviewCount": { "$sum": 1}
}},
{ "$unwind": "$tags" },
{ "$group": {
"_id": {
"company": "$_id.company",
"model": "$_id.model",
"tag": "$tags"
},
"tagCount": { "$sum": 1 }
}},
{ "$group": {
"_id": {
"company": "$_id.company",
"model": "$_id.model",
},
"tags": { "$push": { "tag": "$_id.tag", "count": "$tagCount" },
"count": { "$sum": "$reviewCount" }
}}
但我得到了一个空数组作为响应 您所看到的问题是,您希望在一些其他分组条件中计算数组中某些数据(即“标记”)的不同发生率,然后在删除“标记”并将其作为数组放入结果中后,仅计算其他条件本身的不连续发生率
这个解决方案很合乎逻辑,所以如果你后退一步看看数据,考虑一下这个传真:
{“a”:“a”,“b”:“b”,“c”:[“c”,“d”]}
{“a”:“a”,“b”:“b”,“c”:[“c”,“d”]}
{“a”:“a”,“b”:“b”,“c”:[“d”,“e”]}
{“a”:“a”,“b”:“b”,“c”:[“d”,“e”]}
{“a”:“a”,“b”:“b”,“c”:[“e”,“f”]}
总共有“五个”文档具有相同的“a”和“b”值,当然“c”也会有不同的值。要获得不同的“c”计数,您需要在“a”、“b”和“c”上:
{“$unwind”:“$c”},
{“$组”:{
“_id”:{
“a”:“$a”,
“b”:“$b”,
“c”:“$c”
},
“计数”:{“$sum”:1}
}},
看看结果:
{u id:{“a”:“a”,“b”:“b”,“c”:“e”},“count”:3}
{u id:{“a”:“a”,“b”:“b”,“c”:“f”},“count”:1}
{u id:{“a”:“a”,“b”:“b”,“c”:“d”},“count”:4}
{u id:{“a”:“a”,“b”:“b”,“c”:“c”},“count”:2}
根据可用的不同值,“唯一”组合已下降到“四个”文档。现在你可以看一下,然后说“总计数加起来是‘十’,数组总是有‘两’个元素,所以这意味着‘五’个元素,对吗?”,但这是一个真实的场景,数组长度会有所不同
那你怎么计算文件的数量呢?从这里开始,你不能。在单个聚合管道中唯一可以做的事情是首先在“a”和“b”上使用$group
,使用$push
将所有数组内容保留在“c”中。
这允许您将“a”和“b”组合正确地计算为“五”
然后您将$unwind
“两次”,因为这是一个数组数组,并从开始计数这些不同的键的位置继续,保持$first
在“对”上出现初始计数
{“$group”:{
“_id”:{
“a”:“$a”,
“b”:“$b”
},
“c”:{“$push”:“$c”},
“计数”:{“$sum”:1}
}},
{“$unwind”:“$c”},
{“$unwind”:“$c”},
{“$组”:{
“_id”:{
“a”:“$\u id.a”,
“b”:“$\u id.b”,
“c”:“$c”
},
“docCount”:{“$first”:“$count”},
“计数”:{“$sum”:1}
}},
{“$组”:{
“_id”:{
“a”:“$\u id.a”,
“b”:“$\u id.b”
},
“tags”:{“$push”:{“tag”:“$c”,“count”:“$count”},
“计数”:{“$first”:“$docCount”}
}}
但这并不是“有效的”,因为你们是分组在一起,然后“分开”只是为了增加其他的东西
处理此问题的“有效”方法是运行“两个”聚合操作,并以“并行”方式进行。然后,您可以在一个简单的散列合并中组合操作的结果,或者使用类似的方法,但使用MongoDB集合处理方式:
var async=require('async'),
mongoose=require('mongoose'),
Schema=mongoose.Schema,
DataStore=require('nedb'),
db=新数据存储();
猫鼬mongodb://localhost/test');
风险值数据=[
{“a”:“a”,“b”:“b”,“c”:[“c”,“d”]},
{“a”:“a”,“b”:“b”,“c”:[“c”,“d”]},
{“a”:“a”,“b”:“b”,“c”:[“d”,“e”]},
{“a”:“a”,“b”:“b”,“c”:[“d”,“e”]},
{“a”:“a”,“b”:“b”,“c”:[“e”,“f”]}
];
var dataSchema=新模式({
a:弦,
b:绳子,
c:[字符串]
});
var Data=mongoose.model('Data',dataSchema',Data');
异步系列(
[
函数(回调){
async.each([Data],函数(模型,回调){
删除({},回调);
},回调);
},
函数(回调){
async.each(数据、函数(文档、回调){
数据创建(单据、回拨);
},回调);
},
函数(回调){
异步并行(
[
函数(回调){
数据聚合(
[
{“$组”:{
“_id”:{
“a”:“$a”,
“b”:“$b”
},
“计数”:{“$sum”:1}
}}
],
功能(错误、结果){
如果(错误)回调(错误);
each(结果、函数(结果、回调){
db.update(
{“key”:结果。_id},
{“$set”:{“count”:result.count},
{“upsert”:true},
回拨
);
},回调);
}
);
},
函数(回调){
数据聚合(
[
{“$unwind”:“$c”},
{“$组”:{
“_id”:{
“a”:“$a”,
“b”:“$b”,
“c”:“$c”
},
“计数”:{“$sum”:1}
}},
{“$组”:{