Sort Sub Documents in MongoDB

2019-01-26 05:34发布

问题:

Is there a way to sort sub docs in a mongo query? Example(Blog Collection):

{
    "_id" : ObjectId("4c69d19532f73ad544000001"),
    "content" : "blah blah blah",
        "comments" : {
{"author": "jim",   "content":"comment content 1", "date" : "07-24-1995"},
{"author": "joe",   "content":"comment content 2",  "date" : "07-24-1996"}
{"author": "amy", "content":"comment content 3", "date" : "09-10-1999"}
        }
}
{
    "_id" : ObjectId("4c69d19532f73ad544000002"),
    "content" : "blah blah blah",
        "comments" : {
{"author": "jim",   "content":"comment content 1",  "date" : "07-24-1995"},
{"author": "joe",   "content":"comment content 2",  "date" : "07-24-1996"}
{"author": "amy", "content":"comment content 3",  "date" : "07-24-1997"}
        }
}

I want to get my blog posts ordered in however way I decide and then have comments ordered within my blog posts by reverse order by date or any other sorting I want. Is that possible with mongoDB?

回答1:

In mongo version 2.4 or above, you can use $sort while updating. The new modifier let you sort sub document.

More information could read this page, http://docs.mongodb.org/manual/reference/operator/sort/



回答2:

It's not possible directly out of MongoDB, however when you pull the document you can then sort the array as if it was an array of objects, using whatever native sort method your language has. This is how I do comments on my blog with MongoDB.

PHP Code

/* Takes an array of comments and turns them into native objects */
public static function loadMany($pcomments)
{
    $comments = array();
    if(isset($pcomments) && count($pcomments) > 0)
    {
        foreach($pcomments as $key => $comment)
        {
            $comment['data']['index'] = $key;
            $comments[] = Comment::loadOne($comment['data']);
        }
    }
    usort($comments, "comment_compare");
    return $comments;
}

/* Compares comment timestamps */
function comment_compare($a, $b)
{
    if($a->timestamp->sec == $b->timestamp->sec)
    {
        return 0;
    }
    return ($a->timestamp->sec < $b->timestamp->sec) ? -1 : 1;
}


回答3:

I dont think you can. I raised same question on the forums.