对象数组多字段MongoDB查询
我是MongoDB的新手,我有一个非常复杂的需求,我正在尝试编写一个查询。有没有可能为这个需求编写mongodb查询 示例Mongodb行:对象数组多字段MongoDB查询,mongodb,mongodb-query,Mongodb,Mongodb Query,我是MongoDB的新手,我有一个非常复杂的需求,我正在尝试编写一个查询。有没有可能为这个需求编写mongodb查询 示例Mongodb行: Row1 --> { array1:[ { type=“abc”, action=“taken”, points=10}, { type=“abc”, action=“given”, points=20}, { type=“xyz”, action=“given”, po
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
}
要求:
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
}
过滤条件:
仅当type=“abc”
和差异(当action=“given”
时的点-当action=“take”
时的点)大于0时返回行
分类:
行需要按照(当action=“给定”和type=“xyz”
时的点)和(当action=“taked”
和type=“xyz”
时的点)之间的差异降序排序
预期输出::
输出说明::
第2行不会出现在输出中,因为不满足筛选条件(它在数组中没有任何带有type=“abc”
)的元素)
由于排序条件(第3行的差值大于第1行-->(当action=“given”和type=“xyz”和action=“take”和type=“xyz”和type=“xyz”
时的点)和(当action=“taked”
和type=“xyz”
时的点)在响应中位于第1行之前
(例如:)
[只需点击“运行”按钮]
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"}
}
])
你能举一些可能的预期结果的例子吗?@Haruo谢谢你看我的问题。我已经添加了预期输出和解释。现在我可以理解关于您的问题的规则了。我将尝试建立一个可以解决您的问题的查询。感谢您花时间回复。在$lookup from“collection”中,我们需要向该字段传递什么?即使有许多行满足条件“collection”是集合的名称,我也没有得到任何结果。在我的情况下,集合的名称必须是“集合”。在您的情况下,必须是您的MongoDB上的收藏名称。谢谢@Haruo。谢谢你的帮助。我正在测试查询,我注意到的一件事是,响应中的每个字段都是一个数组,如下所示。有可能改变它吗“_id”:[ObjectId”(“5dbb1d0f9a17899b8ba690d6”),“array1”:[[]]``看起来在action=“taked”时也没有减去值。它给了我相同的值:(这个查询在第35行后面的else部分中添加$cond后运行良好。但是每个字段仍然是一个数组。尝试找出它。
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
}
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"}
}
])