Mongodb中对Documents的子集筛选

MongDB是一种开源的文档型数据库(document database),它可以通过自己BSON存储JSON形式的数据。因为以documents的形式存储在数据库中,起初进行CRUD时候用起来比较麻烦,比如要查询doc中子集的子集。经过一段时间的探索和努力以后,发现通过aggregate方法,完完全全体现啦它的灵活性和扩展性。

下面举个查询的例子:

如下图,一个collection中包含了一个复杂的document:

document={
    "_id" : ObjectId("58046aee430e9c11109c3de2"),
    "texts" : [ 
        {
            "time" : "2016-10-17-14-00",
            "number" : "12345678988",
            "name" : "",
            "io" : 0.0
        }, 
        {
            "time" : "2016-10-17-14-00",
            "number" : "12345678988",
            "name" : "",
            "io" : 0.0
        }, 
        {
            "time" : "2016-10-17-14-00",
            "number" : "12345678988",
            "name" : "",
            "io" : 0.0
        }, 
        {
            "time" : "2016-10-17-14-00",
            "number" : "12345678988",
            "name" : "",
            "io" : 0.0
        }
    ],
    "calls" : [ 
        {
            "time" : "2016-10-17-14-00",
            "number" : "12345678988",
            "name" : "",
            "io" : 1.0,
            "duration" : 60.0
        }, 
        {
            "time" : "2016-10-17-14-00",
            "number" : "12345678988",
            "io" : 1.0,
            "duration" : 60.0
        }
    ]
}

要对document中两个field的value数组进行按时间筛选,返回符合要求的list。仅用MongoDB官网那些基础的find()之类的方法无法达到要求,可以通过aggregate的project ,unwind方法实现:

info = document.aggregate([
                {"$project": {
                    data['type']:{
                        "$filter":{
                            "input":  "$" + data['type'],
                            "as": "item",
                            "cond": {"$and":[
                                {"$lte": ["$$item.time", end]},
                                {"$gte": ["$$item.time", start]}
                            ]}
                        }
                    }
                }},
                {"$unwind": "$" + data['type']},
                {"$project": type_format(data['type'])}
            ])
def type_format(type):
    r = {"_id": 0}
    for k in document[type][0]:
        r[k] = '$' + type + '.' + k
    return r

 
  
 
  


data['type'] 为所要查询的field。

MongoDB 的aggregate方法有一个pipeline的概念,可以将doc数据经过层层处理,向后传送。

如上例,

1、先通过第一个project将所要的field按filter条件的values都筛出来,作为向下的输入;

2、再通过unwind使其作为当先的context(替代之前的document)

3、最后通过project将所要求的格式list输出。

Over.

你可能感兴趣的:(Python,Database,MongoDB)