はじめまして。トンペティです。
今日は、momgoDBのドキュメント内のフィールドをソートする方法を紹介します。
フィールドの並び順に一貫性が無い
ドキュメント指向型DBのmongoDBは、ドキュメントを登録したときのフィールドの並び順がそのまま反映されるので、
同じコレクションから取得した複数のドキュメントを比べてみると、フィールドの並び順はバラバラで、一貫性がありません。
(mongoDBの特性については、「MongoDBの所感について」の記事を一読ください。)
例えば、shopAというコレクションがあるとします。
1 2 3 4 5 6 7 8 9 |
// コレクションからドキュメントを取得する db.shopA.find() // 実行結果 { "_id": 1, "name": "いちご", "price": 150, "code": "A01" }, { "_id": 4, "name": "はくさい", "price": 500, "code": "A04" }, { "_id": 3, "code": "A03", "price": 400, "name": "ほうれんそう" }, { "_id": 2, "code": "A02", "price": 800, "name": "にく" } |
ありのままのドキュメントを取得してみると、フィールドの並び順が
「_id > name > price > code」だったり、
「_id > code > price > name」だったりと、一貫性がありません。
では、ドキュメントをソートしてみたらどうでしょう。
1 2 3 4 5 6 7 8 9 |
// コレクションからドキュメントをソートして取得する db.shopA.find().sort({"code": 1}) // 実行結果 { "_id": 1, "name": "いちご", "price": 150, "code": "A01" }, { "_id": 2, "code": "A02", "price": 800, "name": "にく" }, { "_id": 3, "code": "A03", "price": 400, "name": "ほうれんそう" }, { "_id": 4, "name": "はくさい", "price": 500, "code": "A04" } |
ドキュメントをソートしたところでフィールドの並び順は変わりません。無駄無駄です。
プログラミングで扱うときは、取得したドキュメントのフィールド名を指定するので、フィールドの並び順はそれほど重要ではありません。
しかし、人の手で作業するときは、フィールドの並び順はとても重要です。
例えばよくあるのが、取得したドキュメント同士の差分の比較です。
実際は差がないのにフィールドの並びが違っているだけで全く別ものに見えてしまいます。
手作業でフィールドを並べ替えるのも大変な手間です。
そこで必要になるのが、ドキュメント内のフィールドのソート、なのですが...
その方法は存外知られていないようで、実際この記事を書くにあたり、
検索サイトを探っても、chatGPTに聞いても、最適な情報は得られませんでした。。
じゃあ、そんなもの本当は無いんじゃないの?と疑ってしまいますが、
あります。フィールドをソートする方法はありまぁす。
震えるぞハート。燃え尽きるほどヒート。並ぶぞフィールドのソート。
誰も知らないmongoDBの秘技を、いまこそ伝授いたします。
フィールドをソートする
使うのはズバリ、sortDoc()関数です。
1 2 3 4 5 6 7 8 9 10 11 |
// フィールドをソートして取得する sortDoc(db.shopA.find().sort({"code": 1}).toArray()) // 実行結果 [ { "_id": 1, "code": "A01", "name": "いちご", "price": 150 }, { "_id": 2, "code": "A02", "name": "にく", "price": 800 }, { "_id": 3, "code": "A03", "name": "ほうれんそう", "price": 400 }, { "_id": 4, "code": "A04", "name": "はくさい", "price": 500 } ] |
sortDoc()の引数として任意のfind()クエリに.toArray()をつけたものを指定するだけです。
フィールドの並び順が「_id > code > name > price」に統一され、とても見やすくなりました。
注意点としては、sortDoc()の実行結果は[]で囲われた配列形式で返ってきます。
なので、配列だと支障がある、扱いづらい、などと不満に感じる方には、さらに上級な書き方をお勧めします。
1 2 3 4 5 6 7 8 9 |
// ラムダ式でフィールドをソートして取得する db.shopA.find().sort({"code": 1}).forEach(function(x){print(sortDoc(x))}) // 実行結果 { "_id": 1, "code": "A01", "name": "いちご", "price": 150 }, { "_id": 2, "code": "A02", "name": "にく", "price": 800 }, { "_id": 3, "code": "A03", "name": "ほうれんそう", "price": 400 }, { "_id": 4, "code": "A04", "name": "はくさい", "price": 500 } |
forEach()でラムダ式を使っているので、ちょっと難しい書き方ではありますが、
実行結果は配列ではなく、もともとのfind()の実行結果と同じ形式で返すことができます。
任意のfind()クエリの後ろに .forEach(function(x){print(sortDoc(x))}) という決まり文句をつけるだけなので、
慣れれば大したことありません。私はいつもこの書き方でsortDoc()を使っています。
いかがだったでしょうか。
mongoDB戦士ならば、必ず役に立つ時が来るはずです。是非、習得して使ってみてください。