简体   繁体   中英

How to convert this sql query to mongodb

考虑在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"
        }
      }
    ])

  • The 1st pipeline operation $project calculates the total
  • The 2nd pipeline operation $project is used to check if the total matches the num2. This is needed as we cannot use the comparision operation of num2 with total in the $match pipeline operation
  • The 3rd pipeline operation matches if areEqual is true
  • The 4th pipeline operation $project is just used for projecting the fields

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM