[解決済み] MongoDBの$in句は順序を保証するか?
2022-10-21 18:10:05
質問
MongoDBの
$in
節を使うとき、返されるドキュメントの順番は常に配列の引数の順番と同じになるのでしょうか?
どのように解決するのですか?
前述のように、$in句の配列の引数の順序は、ドキュメントが取得される方法の順序を反映しません。それはもちろん、自然な順序または示されるように選択されたインデックス順序になります。
この順序を保持する必要がある場合、基本的に2つのオプションがあります。
の値でマッチングしていたとしましょう。
_id
に渡される配列と、 ドキュメント中の
$in
として
[ 4, 2, 8 ]
.
集計を用いたアプローチ
var list = [ 4, 2, 8 ];
db.collection.aggregate([
// Match the selected documents by "_id"
{ "$match": {
"_id": { "$in": [ 4, 2, 8 ] },
},
// Project a "weight" to each document
{ "$project": {
"weight": { "$cond": [
{ "$eq": [ "$_id", 4 ] },
1,
{ "$cond": [
{ "$eq": [ "$_id", 2 ] },
2,
3
]}
]}
}},
// Sort the results
{ "$sort": { "weight": 1 } }
])
というわけで、これが展開された形になります。基本的にここで起こることは、値の配列が
$in
に渡されると同時に、quot;nested"
$cond
ステートメントを作成して、値をテストし、適切な重みを割り当てています。このquot;weight"値は配列内の要素の順序を反映しているので、その値をソートステージに渡すことで、必要な順序で結果を得ることができます。
もちろん、実際にコードでパイプラインステートメントを構築するには、このようにします。
var list = [ 4, 2, 8 ];
var stack = [];
for (var i = list.length - 1; i > 0; i--) {
var rec = {
"$cond": [
{ "$eq": [ "$_id", list[i-1] ] },
i
]
};
if ( stack.length == 0 ) {
rec["$cond"].push( i+1 );
} else {
var lval = stack.pop();
rec["$cond"].push( lval );
}
stack.push( rec );
}
var pipeline = [
{ "$match": { "_id": { "$in": list } }},
{ "$project": { "weight": stack[0] }},
{ "$sort": { "weight": 1 } }
];
db.collection.aggregate( pipeline );
mapReduceを用いたアプローチ
もちろん、これがあなたの感性にとって重く感じられるなら、mapReduceを使って同じことをすることができます。
var list = [ 4, 2, 8 ];
db.collection.mapReduce(
function () {
var order = inputs.indexOf(this._id);
emit( order, { doc: this } );
},
function() {},
{
"out": { "inline": 1 },
"query": { "_id": { "$in": list } },
"scope": { "inputs": list } ,
"finalize": function (key, value) {
return value.doc;
}
}
)
そしてそれは基本的に、出力される "key" 値が入力配列の中でどのように発生するかの "index order" にあることに依存しています。
つまり、これらは本質的に、入力リストの順序を維持して
$in
条件への入力リストの順序を維持する方法です。
関連
-
[解決済み】Mongod が /data/db フォルダがないと文句を言う問題
-
[解決済み】SocketException: アドレスはすでに使用中です。
-
[解決済み] 配列のサイズが1より大きい文書を検索します。
-
[解決済み] 配列フィールドが空でない MongoDB レコードを検索する
-
CentOS7に新規インストールしたMongodbの初期設定
-
[解決済み] or' 条件を含む MongoDB クエリ
-
[解決済み] 特定の値を含む配列で文書を検索する
-
[解決済み] MongoDB コレクションのオブジェクト配列で、問い合わせた要素のみを取得する
-
[解決済み】Dockerコンテナのディスク使用量を分析する方法
-
[解決済み】MongoDB Javaドライバが条件付きで乱数ジェネレータを使用するのはなぜですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] MongoDB - 管理者ユーザが認証されていない
-
[解決済み] Mongodb: ensureIndex をいつ呼び出すか?
-
[解決済み] MongoDB Compass フィルタ (クエリ)
-
[解決済み] HomebrewでMongoDBをインストールする
-
[解決済み] 同じデータベース内でコレクションをコピーする最も速い方法は何ですか?
-
[解決済み] mongoDB の文字列フィールドの値の長さ
-
問題が発生しました -----mongodb-------Uncaught TypeError: 未定義のプロパティ 'value' を読み取れませんでした。
-
MongoDBラーニングノート
-
[解決済み] ソート順を指定しない場合、MongoDBはどのようにレコードをソートするのですか?
-
[解決済み] MongoDBのマルチテナントデータベースへの推奨されるアプローチとは?