考虑在sql server中编写的这个查询,我将如何有效地将其转换为mongodb:
select * from thetable where column1 = column2 * 2
You can use below aggregation.
You project a new field comp
to calculate the expression value followed by $match
to keep the docs with eq(0) value and $project
with exclusion to drop comp
field.
db.collection.aggregate([
{ $addFields: {"comp": {$cmp: ["$column1", {$multiply: [ 2, "$column2" ]} ]}}},
{ $match: {"comp":0}},
{ $project:{"comp":0}}
])
If you want to run your query in mongo Shell, try below code,
db.thetable .find({}).forEach(function(tt){
var ttcol2 = tt.column2 * 2
var comapreCurrent = db.thetable.findOne({_id : tt._id,column1 : ttcol2});
if(comapreCurrent){
printjson(comapreCurrent);
}
});
I liked the answer posted by @Veeram but it would also be possible to achieve this using $project and $match pipeline operation. This is just for understanding the flow
Assume we have the below 2 documents stored in a collection 集合中
{ "_id" : ObjectId("58a055b52f67a312c3993553"), "num1" : 2, "num2" : 4 } { "_id" : ObjectId("58a055be2f67a312c3993555"), "num1" : 2, "num2" : 6 }
Now we need to find if num1 = 2 times of num2 (In our case the document with _id ObjectId("58a055b52f67a312c3993553") will be matching this condition)
db.math.aggregate([ { "$project": { "num2": { "$multiply": ["$num2",1] }, "total": { "$multiply": ["$num1",2] }, "doc": "$$ROOT" } }, { "$project": { "areEqual": {"$eq": ["$num2","$total"] }, doc: 1 } }, { "$match": { "areEqual": true } }, { "$project": { "_id": 1, "num1": "$doc.num1", "num2": "$doc.num2" } } ])
In the 1st pipeline operation I have multiplied num2 with 1 as num1 and num2 are stored as integers and $multiply returns double value. 在第一个管道操作中,我将num2乘以1作为num1,num2作为整数存储,$ multiply返回double值。 So incase I do not use $mutiply for num2, then it tries to match 4 equals 4.0 which will not match the document.
Certainly no need for multiple pipeline stages when a single $redact
pipeline will suffice as it beautifully incorporates the functionality of $project
and $match
pipeline steps. Consider running the following pipeline for an efficient query:
db.collection.aggregate([
{
"$redact": {
"$cond": [
{
"$eq": [
"$column1",
{ "$multiply": ["$column2", 2] }
]
},
"$$KEEP",
"$$PRUNE"
]
}
}
])
In the above, $redact
will return all documents that match the condition using $$KEEP
and discards those that don't match using the $$PRUNE
system variable.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.