我正在尝试创建一个聚合MongoDB查询。
数据结构:
{
"object_name": Example,
"values": [ {"name":"value1", "value":1},
{"name":"value2", "value":10},
{"name":"total", "value":105}
}
目标:找到对象名称,其中value1/total > 0.5
和value2/total > 0.25
和total > 100
。
数据以这种方式进行结构,以在value_name和value字段上提供索引。
我尝试过的-与以下管道聚合:
$ match:过滤总计> 100的文档:
$match: { values: { $elemMatch: { value_name: "total", value: {$gte: 100 }
$ project:仅获取我们需要的value_names(有近200个不同的名称)
$project: {
values: {
$filter: {
input: "$values",
as: "value",
cond: { $or: [
{ $eq: [ "$$value.name", "name1"] },
{ $eq: [ "$$value.name", "name2"] },
{ $eq: [ "$$value.name", "total"] },
] }
}
},
name: 1
}
然后,{ $unwind: "$values" }
在这里,我可以从$group
到$divide: name1/total, name2/total
,但是我一直在坚持如何获取这些值。
我不能简单地做stats.value:
,因为它不知道我指的是哪个值。我相信$group
不能$elemMatch
也不能匹配名称。
如果有更简单的解决方案,我将非常感谢您的投入。
答案 0 :(得分:1)
您可以使用$arrayToObject运算符将数组转换为对象,并添加tmp
字段以轻松访问value1
,value2
,total
值>
db.collection.aggregate([
{
$addFields: {
tmp: {
$arrayToObject: {
$map: {
input: "$values",
as: "value",
in: {
k: "$$value.name",
v: "$$value.value"
}
}
}
},
name: 1
}
},
{
$match: {
$expr: {
$and: [
{
$gt: [
{
$divide: [
"$tmp.value1",
"$tmp.total"
]
},
0.5
]
},
{
$gt: [
{
$divide: [
"$tmp.value2",
"$tmp.total"
]
},
0.25
]
},
{
$gt: [
"$tmp.total",
100
]
}
]
}
}
},
{
$project: {
tmp: 0
}
}
])
答案 1 :(得分:1)
请尝试:
name : total
和value > 100
。name : total
添加对象
记录。value1/total > 0.5
和value2/total > 0.25
。1
,则这两个条件是
见过。object_name
查询:
db.yourCollectionName.aggregate([{ $match: { values: { $elemMatch: { name: "total", value: { $gte: 100 } } } } },
{
$addFields: {
totalValue: {
$arrayElemAt: [{
$filter: {
input: "$values",
as: "item",
cond: { $eq: ["$$item.name", 'total'] }
}
}, 0]
}
}
},
{
$project: {
values: {
$filter: {
input: "$values",
as: "value",
cond: {
$or: [
{ $cond: [{ $eq: ["$$value.name", "value1"] }, { $gt: [{ $divide: ["$$value.value", '$totalValue.value'] }, 0.5] }, false] },
{ $cond: [{ $eq: ["$$value.name", "value2"] }, { $gt: [{ $divide: ["$$value.value", '$totalValue.value'] }, 0.25] }, false] }
]
}
}
}, object_name: 1
}
}, {
$match: {
$expr: { $gt: [{ $size: "$values" }, 1] }
}
}, { $project: { object_name: 1, _id: 0 } }])
收集数据:
/* 1 */
{
"_id" : ObjectId("5e20bd94d02e05b694d55fa5"),
"object_name" : "Example",
"values" : [
{
"name" : "value1",
"value" : 1
},
{
"name" : "value2",
"value" : 10
},
{
"name" : "total",
"value" : 105
},
{
"name" : "total1",
"value" : 105
}
]
}
/* 2 */
{
"_id" : ObjectId("5e20bdb1d02e05b694d56490"),
"object_name" : "Example2",
"values" : [
{
"name" : "value1",
"value" : 1
},
{
"name" : "value2",
"value" : 10
},
{
"name" : "total",
"value" : 5
},
{
"name" : "total1",
"value" : 5
}
]
}
/* 3 */
{
"_id" : ObjectId("5e20d1b7d02e05b694d7c57a"),
"object_name" : "Example3",
"values" : [
{
"name" : "value1",
"value" : 100
},
{
"name" : "value2",
"value" : 100
},
{
"name" : "total",
"value" : 200
},
{
"name" : "total1",
"value" : 205
}
]
}
/* 4 */
{
"_id" : ObjectId("5e20d1cad02e05b694d7c71c"),
"object_name" : "Example4",
"values" : [
{
"name" : "value1",
"value" : 200
},
{
"name" : "value2",
"value" : 40
},
{
"name" : "total",
"value" : 200
},
{
"name" : "total1",
"value" : 205
}
]
}
/* 5 */
{
"_id" : ObjectId("5e20d1e2d02e05b694d7c933"),
"object_name" : "Example5",
"values" : [
{
"name" : "value1",
"value" : 150
},
{
"name" : "value2",
"value" : 100
},
{
"name" : "total",
"value" : 200
},
{
"name" : "total1",
"value" : 205
}
]
}
结果:
/* 1 */
{
"object_name" : "Example5"
}