Php Mongodb聚合排序关联数组

Php Mongodb聚合排序关联数组,php,mongodb,Php,Mongodb,由于$位置运算符不适用于2级深嵌套数组,我正在使用替代模式为嵌套数组启用更新功能 我有一个嵌套文档,如下所示 { '_id' : 1234, 'bio' : { 'achievements' : { 'Yhg87Hghg65' : { 'title' : 'Achievement 1', 'score' : 95, 'year' : 2004 }, '67gjfyg

由于
$
位置运算符不适用于2级深嵌套数组,我正在使用替代模式为嵌套数组启用更新功能

我有一个嵌套文档,如下所示

{
  '_id' : 1234,
  'bio' : {
     'achievements' : {
        'Yhg87Hghg65' : {
           'title' : 'Achievement 1',
           'score' : 95,
           'year' : 2004
        },
        '67gjfygt8Hd' : {
           'title' : 'Achievement 2',
           'score' : 89,
           'year' : 2003
        },
        'Lkoh8hHggf7' : {
           'title' : 'Achievement 1',
           'score' : 90,
           'year' : 2005
        }
     }
  }
}
现在,使用mongodb聚合管道,我可以在PHP中获取如下内容

$doc = $collection -> aggregate(
  array(
    '$match' => array(
        '_id' => 1234
     )
  ),
  array(
    '$project' => array(
       'bio.achievements' => 1
    )
  )
);

到目前为止,一切正常。但我需要按年度对成绩进行分类。在
'$project'
之前使用普通的
'$sort'
是行不通的,因为成就不是数组,它们是值为数组的字段。如果有人知道如何实现它,请给我一些提示。

当你的对象在地图中,用javascript,你永远不能保证检索的顺序。MongoDb也没有任何内置的方法来对映射的属性进行排序。因此,您需要在客户端进行订购。您的代码可能如下所示:

var result = db.collection.find({"_id":1234},{"bio.achievements":1}).
       map(function(doc){
            var achievements = (Object.keys(doc.bio.achievements)).
            map(function(key){
            doc.bio.achievements[key]["key"] = key;
            return doc.bio.achievements[key];
           });
           achievements.sort(function(a,b){
           return a.year-b.year;
         })
      doc.bio.achievements = achievements;
      return doc;
  })
话虽如此,存储有序对象的最佳方法是将它们存储在数组中。如果您可以按以下方式更改模式:

{
  '_id' : 1234,
  'bio' : {
     'achievements' : [
        {  'id':'Yhg87Hghg65',
           'title' : 'Achievement 1',
           'score' : 95,
           'year' : 2004
        },
        {
           'id':'67gjfygt8Hd',
           'title' : 'Achievement 2',
           'score' : 89,
           'year' : 2003
        },
        {  'id':'Lkoh8hHggf7',
           'title' : 'Achievement 1',
           'score' : 90,
           'year' : 2005
        }
     ]
  }
}
您可以轻松地聚合所需的结果:

db.collection.aggregate([
{$match:{"_id":1234}},
{$unwind:"$bio.achievements"},
{$sort:{"bio.achievements.year":1}},
{$group:{"_id":"$_id","achievements":{$push:"$bio.achievements"}}}
])
订单样本:

{
        "_id" : 1234,
        "achievements" : [
                {
                        "id" : "67gjfygt8Hd",
                        "title" : "Achievement 2",
                        "score" : 89,
                        "year" : 2003
                },
                {
                        "id" : "Yhg87Hghg65",
                        "title" : "Achievement 1",
                        "score" : 95,
                        "year" : 2004
                },
                {
                        "id" : "Lkoh8hHggf7",
                        "title" : "Achievement 1",
                        "score" : 90,
                        "year" : 2005
                }
        ]
}
由于$positional运算符不适用于2级深嵌套数组,因此 am使用替代架构为嵌套的 数组

您需要以这样一种方式设计您的架构,即可以使用
$
操作符进行更新,就发布的示例而言,可以使用位置操作符进行更新,类似于下面的操作:

    db.collection.update({"bio.achievements.id":"Yhg87Hghg65"},
                         {$set:{"bio.achievements.$.year":2006}});