我是MongoDB的新手,我有一个非常复杂的要求,因此我试图编写查询。有什么办法可以为此要求编写mongodb查询吗?
示例Mongodb行:
Row1 --> {
array1:[
{ type=“abc”, action=“taken”, points=10},
{ type=“abc”, action=“given”, points=20},
{ type=“xyz”, action=“given”, points=40},
{ type=“xyz”, action=“taken”, points=30}
]
// other fields
}
Row2 --> {
array1:[
{ type=“xyz”, action=“given”, points=50},
{ type=“xyz”, action=“taken”, points=40}
]
// other fields
}
Row3 --> {
array1:[
{ type=“abc”, action=“taken”, points=100},
{ type=“abc”, action=“given”, points=200},
{ type=“xyz”, action=“given”, points=500},
{ type=“xyz”, action=“taken”, points=400}
]
// other fields
}
要求:
过滤条件:
仅当type="abc"
和有所不同时返回行(action="given"
时的点-action="taken"
时的点)> 0
排序:
行需要按照(action="given"
和type="xyz"
时的点与(action="taken"
和type="xyz"
时的点)之间的差的降序进行排序
预期输出::
Row3 --> {
array1:[
{ type=“abc”, action=“taken”, points=100},
{ type=“abc”, action=“given”, points=200},
{ type=“xyz”, action=“given”, points=500},
{ type=“xyz”, action=“taken”, points=400}
]
// other fields
}
Row1 --> {
array1:[
{ type=“abc”, action=“taken”, points=10},
{ type=“abc”, action=“given”, points=20},
{ type=“xyz”, action=“given”, points=40},
{ type=“xyz”, action=“taken”, points=30}
]
// other fields
}
输出说明::
第2行将不会出现在输出中,因为不满足过滤条件(该数组中的type="abc"
中没有任何元素)
由于排序条件,行3在响应的第1行之前(此差异值在第3行中比第1行大->(指向action="given"
和type="xyz"
时的点)和(指向{ {1}}和action="taken"
))
答案 0 :(得分:0)
尝试一下:
(位于https://mongoplayground.net/p/-rSHiqBwlEJ的工作示例)
[只需单击“运行”按钮]
db.collection.aggregate([
{
// 01) Filtering out documents that have type "abc"...
$match: {"array1.type" : "abc" },
},
{
// 02) Transforming every element of the array in one document...
$unwind: "$array1",
},
{
// 03) Summing the values by type ...
$group: {
_id: '$_id',
totalAbc: {
$sum: {
$cond: {
if: {$and:[{$eq: [ "$array1.action", "given"]},{$eq: [ "$array1.type", "abc"]}]},
then: "$array1.points",
else: {
if: {$and:[{$eq: [ "$array1.action", "taken"]},{$eq: [ "$array1.type", "abc"]}]},
then: {$multiply: ["$array1.points", -1]},
else: 0
}
}
}
},
totalXyz: {
$sum: {
$cond: {
if: {$and:[{$eq: [ "$array1.action", "given"]},{$eq: [ "$array1.type", "xyz"]}]},
then: "$array1.points",
else: {
if: {$and:[{$eq: [ "$array1.action", "taken"]},{$eq: [ "$array1.type", "xyz"]}]},
then: {$multiply: ["$array1.points", -1]},
else: 0
}
}
}
},
}
},
{
// 04) Filtering the result where the total of type "abc" is greater than 0...
$match: {"totalAbc": {$gt: 0} }
},
{
// 05) Sorting the result by the total of type "xyz" ...
$sort: { totalXyz : -1 }
},
{
// 06) With id I retrieve all the original document information...
$lookup: {
from: "collection",
localField: "_id",
foreignField: "_id",
as: "temp"
}
},
{
// 07) Designing the information in the same structure as the original documents ...
$project: {"_id": "$temp._id", "array1": "$temp.array1"}
}
])