PHP/Mongo-DB:如何根据特定的数组属性进行排序


PHP / Mongo DB : How to sort by a specific array attribute

我有这样的集合:

"File" 
{ 
"_id" : { "$oid" : "4f730e3bb8be296910000180"}
, "Name" : "File1.jpg"
, "Folders" : [ 
                { "F_id" : { "$oid" : "4f72f503b8be296d78000166"} , "Ord" : 1} 
                , { "F_id" : { "$oid" : "4f730eedb8be296e78000180"} , "Ord" : 3}
            ]
}
{ 
"_id" : { "$oid" : "4f730e3ab8be296978000181"} 
, "Name" : "File2.jpg"
, "Folders" : [ 
                { "F_id" : { "$oid" : "4f72f503b8be296d78000166"} , "Ord" : 2} 
                , { "F_id" : { "$oid" : "4f730eedb8be296e78000180"} , "Ord" : 2}
                , { "F_id" : { "$oid" : "4f730eedb8be296e78000132"} , "Ord" : 1}
            ] 
}
{ 
"_id" : { "$oid" : "4f730e38b8be296e78000182"}
, "Name" : "File3.jpg"
, "Folders" : [ 
                { "F_id" : { "$oid" : "4f72f503b8be296d78000166"} , "Ord" : 3} 
                , { "F_id" : { "$oid" : "4f730eedb8be296e78000180"} , "Ord" : 1}
            ]
}

"文件夹"可以包含更多的元素,并反映文件在哪个文件夹"F_id"中可用,以及文件在该文件夹中的"顺序"。

然后,我想简单地以正确的顺序获得一个文件夹中所有可用的文件。

但当我做一些类似的事情时:

File.fund({"Folders.F_id":{"$oid":4f72f503b8be296d78000166}).sort({"Folders.$.Ord":1});

我无法获得我期望的正确订单!

知道吗??我应该使用Map reduce吗?怎样

谢谢!

在mongodb中使用.sort()进行排序只指对文档本身进行排序,而不是对嵌套在这些文档中的数组中的值进行排序。使用此模式,您将需要在客户端获取文档并对数组中的值进行排序。

谢谢。

我找到了一个使用map/reduce的变通方法,它在这种情况下效果很好。

我把它放在这里,以防其他人质疑:

//
//$folder_Id is the _id of the folder I want to list 
//map function
$mapFunc="function() {
                    var myFolder='". $folder_Id ."';
                    var obj = { // all the elements I need!
                        'Folders': {},
                        'Flds': {},
                        'Crea': {},
                        'TechInfo': {},
                        'Thumbs': {},
                        '_id': null,
                        'Order': null
                    }
                    if (this.Folders)obj.Folders = this.Folders ;
                    if (this.Flds)obj.Flds = this.Flds ;
                    if (this.Crea)obj.Crea = this.Crea ;
                    if (this.TechInfo)obj.TechInfo = this.TechInfo ;
                    if (this.Thumbs)obj.Thumbs = this.Thumbs ;
                    obj._id = this._id ;
                    if (this.Folders) {
                        for(var i=0 ; i< this.Folders.length ;i++){
                            if(this.Folders[i].F_id==myFolder){
                                obj.Order=  this.Folders[i].Ord
                                break;
                            }
                        }
                    }
                    emit( this._id , obj);
                }
        ";
//reduce function
$reduceFunc="function(key, values) {
                    values['_id']=key;
                    return  values  ;
                }
            ";

$mapReduceColl="MR_" . new MongoId();
$command = array(
    'mapreduce' => "File"
    ,'map' => $mapFunc
    ,'reduce' => $reduceFunc
    ,'query' => $query
    //,"verbose"=>true
    ,"out"=>array("replace"=>$mapReduceColl)
);
$statsInfo =  $db->MyDB->command($command);
$statsCollection =  $db->MyDB->selectCollection($statsInfo['result']);
$cursor = $statsCollection->find()->sort(array( $params["ordBy"]=>$params["ordByDir"]))->skip( $skip )->limit(  $nbreParPage );