【问题标题】:How to query documents with embeded array and sort them如何使用嵌入式数组查询文档并对其进行排序
【发布时间】:2016-09-30 19:24:53
【问题描述】:

我在使用 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;
}

这些是用户集合中的数据库文档:

{ 
    "_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"), 
        }
    ]
}

如何使用ID '5705157244ae89863aaeb725' 查询group 中的用户并输入"T1"? Users 集合中的以下查询提供了两个用户,它应该只提供第一个用户,它的组为ID '5705157244ae89863aaeb725',类型为"T1"

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

但不能按joinedAt字段排序

【问题讨论】:

  • 预期文件是什么?只有这一项符合标准? $elemMatch - 在这种情况下可能是你的朋友
  • 您正在使用的查询将返回整个用户记录,并将包含 userGroup 以及其中的所有对象。如果您能解释所需的输出,那么我们可以帮助您。
  • 好的,抱歉,我编辑了我的问题。请检查
  • 这似乎有效:{ userGroups: { $elemMatch: { "group.$id": ObjectId("5705157244ae89863aaeb725"), "type": "T1" } }}
  • 如果我想添加查询并按joinedAt排序怎么办? {"userGroups.joinedAt": -1} 未按预期工作。它根据任何组的joinedAt排序

标签: mongodb symfony mongodb-query doctrine-odm odm


【解决方案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
    }
}

//第一步

db.coll.aggregate([match ])

//第二步

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

//第三步

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

//第四步

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

//步骤 5,6

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

1 和 3 仅选择符合条件的文档,2 - 展开数组元素以分隔文档,4 - 执行排序,5 和 6 用于恢复先前的形状

【讨论】:

  • 感谢您的回答。我需要使用教义来做到这一点
  • see this 你在command 包装器中使用聚合,向谷歌叔叔询问:doctrine aggregation mongo @Fran
猜你喜欢
  • 2012-03-10
  • 1970-01-01
  • 1970-01-01
  • 2012-02-11
  • 1970-01-01
  • 2021-03-24
  • 1970-01-01
  • 2021-08-07
  • 2021-04-14
相关资源
最近更新 更多