我有这样的集合:
"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 );