Как запросить документы с помощью встроенного массива и отсортировать их

У меня проблема с запросом документов с помощью embedMany.

Это мои документы, где пользователь встраивает много групп (которые я называю userGroups).

class User {

    /**
     * @MongoDB\Id
     */
    protected $id;

     /**
      * @MongoDB\Field(type="string")
      */
     protected $name;

    /**
     * @MongoDB\EmbedMany(targetDocument="Group", strategy="setArray")
     * @var UserGroups[]
     */
    protected $userGroups;
}

class UserGroup {

    /**
     * @MongoDB\NotSaved
     * @MongoDB\ReferenceOne(targetDocument="Group")
     * @var Group
     */
    protected $group;

    /**
     * @MongoDB\Field(type="string")
     * @var string
     */
    protected $type;

    /**
     * @MongoDB\Field(type="date")
     * @var \DateTime
     */
    protected $joinedAt;
}

Это документы БД в коллекции User:

{ 
    "_id" : ObjectId("56de151b821b16ac02310a25"), 
    "name" : "Some user name", 
    "userGroups" : [
        {
            "group" : DBRef("groups", ObjectId("5705157244ae89863aaeb725"), "some group name"), 
            "type" : "T1", 
            "joinedAt" : ISODate("2016-05-13T19:59:43.000+0000")
        }, 
        {
            "group" : DBRef("groups", ObjectId("571498f7821b16100c5bcc58"), "some other group name"), 
            "type" : "T1", 
            "joinedAt" : ISODate("2016-05-21T20:07:26.000+0000")
        }, 
        {
            "group" : DBRef("groups", ObjectId("57348618c67940a0528b4567"), "some other group name T2"), 
            "type" : "T2", 
            "joinedAt" : ISODate("2016-05-30T18:07:39.000+0000"), 
        }
    ]
}

{ 
    "_id" : ObjectId("287sd3d728as56dnsdu2hsds782nsdsd"), 
    "name" : "Some other user name", 
    "userGroups" : [
        {
            "group" : DBRef("groups", ObjectId("5705157244ae89863aaeb725"), "some group name"), 
            "type" : "T2", 
            "joinedAt" : ISODate("2016-05-13T19:59:43.000+0000")
        }, 
        {
            "group" : DBRef("groups", ObjectId("57348618c67940a0528b4567"), "some other group name T2"), 
            "type" : "T2", 
            "joinedAt" : ISODate("2016-05-30T18:07:39.000+0000"), 
        }
    ]
}

Как я могу запросить пользователей в group с ID '5705157244ae89863aaeb725' и введите "T1"? Следующий запрос в коллекции Users доставляет обоих пользователей, и он должен доставлять только первого, который имеет группу с ID '5705157244ae89863aaeb725' и введите "T1"

{ userGroups: { $elemMatch: 
               { "group.$id": ObjectId("5705157244ae89863aaeb725"), "type": "T1" } }} 

Но не могу отсортировать их по joinedAt поле

1 ответ

Для сортировки внутреннего поля массива вам нужно использовать структуру агрегации: этот пример содержит шаги, и вы можете удалить их, чтобы увидеть, как изменяется документ

var unwind = {
    $unwind : "$userGroups"
}
var match = {
    $match : {
        "userGroups.group.$id" : ObjectId("5705157244ae89863aaeb725"),
        "userGroups.type" : "T1"
    }
}
var sort = {
    $sort : {
        "userGroups.joinedAt" : -1
    }
}
var reGroup = {
    $group : {
        _id : {
            id : "$_id",
            name : "$name"
        },
        userGroups : {
            $push : "$userGroups"
        }
    }
}
var reShapeDocument = {
    $project : {
        _id : "$_id.id",
        name : "$_id.name",
        userGroups : 1
    }
}

//шаг 1

db.coll.aggregate([match ])

//шаг 2

db.coll.aggregate([match, unwind    ])

//шаг 3

db.coll.aggregate([match, unwind, match,    ])

// шаг 4

db.coll.aggregate([match, unwind, match, sort,  ])

// шаг 5,6

 db.coll.aggregate([match, unwind, match, sort, reGroup, reShapeDocument])

1 и 3 выбирают только критерии соответствия документов, 2 - разматывает элементы массива для разделения документов, 4 - выполняет сортировку, 5 и 6 используются для восстановления предыдущей фигуры

Другие вопросы по тегам