mongodb汇总与额外信息

时间:2016-09-15 21:57:47

标签: mongodb mongodb-aggregation

我有一个mongo集合,其中包含以下文档:

{
    "_id" : ObjectId("57697321c22d3917acd66513"),
    "parent" : "AlphaNumericID",
    "signature" : "AnotherAlphaNumericID",
    "price" : 1638,
    "url" : "http://www.thecompany.com/path/to/page1",
    "date" : ISODate("2016-06-21T17:02:20.352Z"),
    "valid" : true
}

我要做的是运行一个查询,该查询将分组签名,返回最小和最大价格以及相应的网址:

{
        "signature" : "AnotherAlphaNumericID",  
        "min_price" : 1504,
        "min_rent_listing" : "http://www.thecompany.com/path/to/page1",
        "max_price" : 1737,
        "max_price_listing" : "http://www.thecompany.com/path/to/page2",
}

$group字段上运行$signature以获取$min$max是直截了当的,但为了获取实际网址,我将查询拆分为2查询使用$signature返回已排序的文档列表,其中包含从最小到最大的价格,然后(在python代码中)获取第一个和最后一个元素。这工作正常,但有一个查询会很好。

思想?

P.S。

同时'玩弄'运行一个查询为min,一个用于max并'压缩'结果。

1 个答案:

答案 0 :(得分:2)

您可以在$group$project的帮助下玩耍。假设数据集是

{ 
    "_id" : ObjectId("57db28dc705af235a826873a"), 
    "parent" : "AlphaNumericID", 
    "signature" : "AnotherAlphaNumericID", 
    "price" : 1638.0, 
    "url" : "http://www.thecompany.com/path/to/page1", 
    "date" : ISODate("2016-06-21T17:02:20.352+0000"), 
    "valid" : true
}
{ 
    "_id" : ObjectId("57db28dc705af235a826873b"), 
    "parent" : "AlphaNumericID", 
    "signature" : "AnotherAlphaNumericID", 
    "price" : 168.0, 
    "url" : "http://www.thecompany.com/path/to/page2", 
    "date" : ISODate("2016-06-21T17:02:20.352+0000"), 
    "valid" : true
}
{ 
    "_id" : ObjectId("57db28dc705af235a826873c"), 
    "parent" : "AlphaNumericID", 
    "signature" : "AnotherAlphaNumericID", 
    "price" : 163.0, 
    "url" : "http://www.thecompany.com/path/to/page3", 
    "date" : ISODate("2016-06-21T17:02:20.352+0000"), 
    "valid" : true
}
{ 
    "_id" : ObjectId("57db28dc705af235a826873d"), 
    "parent" : "AlphaNumericID", 
    "signature" : "AnotherAlphaNumericID", 
    "price" : 1680.0, 
    "url" : "http://www.thecompany.com/path/to/page4", 
    "date" : ISODate("2016-06-21T17:02:20.352+0000"), 
    "valid" : true
}

在shell中尝试以下查询

db.collection.aggregate([
   {$sort:{price:1}},
   {$group:{
       _id:"$signature", 
       _first:{$first:"$url"},
       _last:{$last:"$url"}, 
       _min:{$first:"$price"}, 
       _max:{$last:"$price"}}
   },
   {$project:{
     _id:0, 
     min:{
       url:"$_first", 
       price:"$_min"}, 
     max:{
       url:"$_last", 
       price:"$_max"}}
   }
])

输出将以最低/最高价格和相应的网址

{ 
    "min" : {
        "url" : "http://www.thecompany.com/path/to/page3", 
        "price" : 163.0
    }, 
    "max" : {
        "url" : "http://www.thecompany.com/path/to/page4", 
        "price" : 1680.0
    }
}

我从原来的答案改变了: _min:{$min:"$price"}, - >使用$first _max:{$max:"$price"}} - >使用$last

原因:我们按价格上升排序进入管道。默认情况下,第一条记录为分钟,最后一条记录为最大记录