使用map-reduce / Aggregation进行MongoDB查询?

时间:2013-12-22 23:24:28

标签: java mongodb mongoose

我在mongo collection中有简单的数据。它看起来像:

{
"_id" : ObjectId("52b73b1318a7be441dbf36b6"),
"nme" : "Vinod Kumar",
"unm" : "vkumar",
"cat" : ISODate("2013-12-22T19:18:43.873Z"),
"act" : [{
    "nme" : "test activity one",
    "dec" : "This is only about test activity",
    "gat" : ISODate("2013-12-25T19:17:00.873Z"),
    "cat" : ISODate("2013-12-22T19:18:43.873Z")
    }]
},

{
"_id" : ObjectId("52b73b1318a7be441dbf36b6"),
"nme" : "Manoj Kumar",
"unm" : "mkumar",
"cat" : ISODate("2013-12-22T19:18:43.873Z"),
"act" : [{
    "nme" : "test activity three",
    "dec" : "This is only about test activity",
    "gat" : ISODate("2013-12-25T19:17:00.873Z"),
    "cat" : ISODate("2013-12-20T19:18:43.873Z")
    },
        {
    "nme" : "test activity two",
    "dec" : "This is only about test activity",
    "gat" : ISODate("2013-12-25T19:17:00.873Z"),
    "cat" : ISODate("2013-12-21T19:18:43.873Z")
    }]
}

我希望得到所有行为(活动)命令cat(创建时间)以及(unm)用户名。我还想添加分页功能,所以我在查询中也需要限制和偏移。最后我期待输出:< / p>

        {
    "nme" : "test activity one",
    "dec" : "This is only about test activity",
    "gat" : ISODate("2013-12-25T19:17:00.873Z"),
    "cat" : ISODate("2013-12-22T19:18:43.873Z"),
    "unm" : "vkumar",
    },
        {
    "nme" : "test activity two",
    "dec" : "This is only about test activity",
    "gat" : ISODate("2013-12-25T19:17:00.873Z"),
    "cat" : ISODate("2013-12-21T19:18:43.873Z"),
    "unm" : "mkumar",
    },
        {
    "nme" : "test activity three",
    "dec" : "This is only about test activity",
    "gat" : ISODate("2013-12-25T19:17:00.873Z"),
    "cat" : ISODate("2013-12-20T19:18:43.873Z"),
    "unm" : "mkumar",
    }

我在这个系列中有200000条记录。任何人都可以帮助我而不建议单独创建活动集合。

是否有使用聚合框架的解决方法,如果是,我该怎么办?由于我需要使用sort,skip和limit,我不知道如何通过聚合和最佳性能来实现这一点。

我尝试了map reduce,但这无济于事,因为map reduce会为每个查询生成静态结果,而使用应用程序的多个用户在使用分页(limit,skip)时可能会产生冲突。

任何帮助或建议都将不胜感激。

由于

这是我当前的查询

$m = new MongoClient();
$c = $m->selectDB("test")->selectCollection("users");

$ops = array(
array(
    '$project' => array(
        "unm" => 1,
        "act" => 1
    )
),
array('$sort' => array('act.cat' => -1 )),
array('$limit' => 10),

);
$results = $c->aggregate($ops);

1 个答案:

答案 0 :(得分:0)

以下是我自己的问题的答案。我现在意识到mongo有隐藏的力量:P

$m = new MongoClient();
$c = $m->selectDB("test")->selectCollection("users");

$ops = array(
array(
'$project' => array(
"unm" => 1,
"act" => 1
)
),
array('$unwind' => '$act'),
array('$match' => array('act.sta' => 1)), // if you want some extra queries. In my case I am checking if status of activity is 1
array('$sort' => array('act.cat' => -1 )), // sort by created time
array('$skip' => $page), // skip int variable
array('$limit' =>$config['per_page']), // limit int variable
);

$results = $c->aggregate($ops); 
print_r($results);