1

mongoDb では、「$queryResult」に記載されている結果を集計で達成しようとしています。コレクションからすべてのレコードを選択し、それらを配列で並べ替えたいと考えています。

データベースに記録

$recordsInDb = [
    ["coreId" => 10, "name" => 'a'],
    ["coreId" => 20, "name" =>'a'],
    ["coreId" => 30,"name" => 'a']
];

クエリの順序

$order = [20,10];

望ましい結果

$queryResult = [
    {coreId:20,name:'a'}
    {coreId:10,name:'a'},
    {coreId:30,name:'a'}
]
4

1 に答える 1

1

順序付けられたリストを持つコレクション内の各ドキュメントで追加の配列フィールドを作成するよりも優れた方法は考えられません。そのフィールドを巻き戻しincludeArrayIndex、演算子のプロパティを使用し$unwindてインデックス位置を生成します。その情報を使用してドキュメントを並べ替え、追加の 10 項演算子を使用$condして論理式を評価array element === coreIdし、結果に応じて true の場合は並べ替えインデックスを返し、それ以外の場合は定数を返しますn > order.length

以下は、上記のアプローチを示していますが、改善の余地は十分にありますが、少なくともある程度の方向性は示されているはずです。もちろん、パイプラインを適切なドライバー言語 (PHP と仮定します) に変換するのはあなた次第です。

var order = [20, 10];
db.records.aggregate([
    { 
        "$project": {
            "coreId" : 1,
            "name" : 1,
            "sortOrder": { "$literal": order } // create an additional field
        }
    },
    { 
        "$unwind": {
            // flatten the above array
            "path": "$sortOrder", 
            // create the index position for each array element
            "includeArrayIndex": "sortIndex", 
        }
    },
    {
        "$project": {
            "coreId": 1,
            "name": 1,
            "sortIndex": {
                 "$cond": [
                    { "$eq": [ "$coreId", "$sortOrder" ] }, 
                    "$sortIndex", 999999 
                 ]
            }
        }
    },
    { "$sort": { "sortIndex": 1 } },
    {
        "$group": {
            "_id": "$coreId",
            "name": { "$first": "$name" },
            "index": { "$first": "$sortIndex" }
        }
    },
    { "$sort": { "index": 1 } },
    { 
        "$project": {
            "_id": 0,
            "coreId" : "$_id",
            "name" : 1
        }
    }
])

サンプル結果

/* 1 */
{
    "name" : "a",
    "coreId" : 20
}

/* 2 */
{
    "name" : "a",
    "coreId" : 10
}

/* 3 */
{
    "name" : "a",
    "coreId" : 30
}
于 2016-09-28T10:14:31.950 に答える