简体   繁体   中英

Convert an SQL into pymongo query

Document prototype:

{
    "d": "D", 
    "g": {
        "c": "C", 
        "a": "A", 
        "b": "B"
    }, 
    "e": "E", 
    "f": "F"
}

What would be the equivalent of:

SELECT a, b, c, d from Table WHERE d='D' AND e='E' GROUP BY a

in mongodb using pymongo?

The following query returns objects:

db.<collection>.find({'d': 'D'}, {'g.c': 1, 'g.a': 1, 'g.b': 1, 'd': 1, '_id': 0})

But, the following doesn't:

db.<collection>.aggregate([{$match:{"d":"D", "e":"E"}},
                           {$group:{_id:"$g.a"}}])

It returns an empty list, not even a query(cursor) object.

Also, how could I include $project into it so that I may restrict the output to the fields of a, b ,cd only?

Note I 've created the collection so as to filter e='E'.

Actually your query is not a valid SQL.

You have to quote strings

SELECT a, b, c, d
from Table
WHERE d='D' AND e='E'
GROUP BY a

And still this query will work only in MySQL. For ANSI SQL (and most implementations) you should specify aggregates for your columns, like

SELECT a, min(b) as b, max(c) as c
from Table
WHERE d='D' AND e='E'
GROUP BY a

then your mongodb query would be like

db.<your collection>.aggregate([
   {$match:{"d":"D", "e":"E"}},
   {$group:{_id:"$g.a", b: { $min: "$g.b"}, c: {$max:"$g.c"}}}
])

if you want an array of a, b, c, d values, this should work:

db.<your collection>.aggregate([
   {$match:{"d": "D", "e": "E"}},
   {
       $group: {
            _id: "$g.a",
            data: {$push: {"a": "$g.a", "b": "$g.b", "c": "$g.c", "d": "$d"}}
       }
   }
])

Just tested this code - it works, here's python code:

>>> cl = MongoClient()
>>> coll = cl["local"]["test3"]
>>> res = coll.aggregate([{"$match":{"d": "D", "e": "E"}},{"$group":{"_id":"$g.a", "data": {"$push":{"a":"$g.a", "b":"$g.b", "c":"$g.c", "d":"$d"}}}}])
>>> res["result"]
[{'_id': 'A', 'data': [{'a': 'A', 'c': 'C', 'b': 'B', 'd': 'D'}, {'a': 'A', 'c': 'K', 'b': u'V', 'd': 'D'}]}]

As you can see the answer by @RomanPekar does actually work:

> db.z.insert({d:'D',g:{c:'C',a:'A',b:'B'},e:'E',f:'F'})
> db.z.aggregate([{$match:{d:'D',e:'E'}},{$group:{_id:'$g.a'}}])
{ "result" : [ { "_id" : "A" } ], "ok" : 1 }

The problem is, most likely, that you are trying to do this in python without changing the syntax. Instead you would run this in python:

db.z.aggregate([{"$match":{"d":"D","e":"E"}},{"$group":{"_id":"$g.a"}}])

For reference: http://api.mongodb.org/python/current/examples/aggregation.html

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