シェアする

はじめに

表示時や取得時にデータを並べ替えることは、ほとんどのデータベースシステムにとって重要な操作であり、他のデータストレージメカニズムと区別するのに役立ちます。格納されている順序とは独立して、さまざまなフィールドの順序付け、優先順位付け、および解釈を操作できることは、データベース自体とその関連クエリシステムの両方において最も有用な機能の1つです。

MongoDBは、クエリから返されるデータの並べ替え方法を制御する多くの方法を提供します。このガイドでは、ユースケースに応じてさまざまな方法でデータを並べ替える方法について説明します。単純な並べ替えと複合並べ替え、並べ替え順序の変更方法、および他の演算子と組み合わせて並べ替えがどのように適用されるかについて説明します。

サンプルデータのセットアップ

並べ替えがどのように機能するかを示すために、students コレクションに含まれる多数のドキュメントをクエリします。studentsコレクションを作成し、以下をコピーアンドペーストすることでクエリするドキュメントを挿入できます。

db.students.insertMany([
{
first_name: 'Carol',
last_name: 'Apple',
dob: ISODate('2010-10-30'),
address: {
street: {
name: 'Flint Rd.',
number: '803',
},
city: 'Camden',
zip: '10832',
},
},
{
first_name: 'Spencer',
last_name: 'Burton',
dob: ISODate('2008-12-04'),
address: {
street: {
name: 'Edgecombe St.',
number: '2083b',
},
city: 'Zoofreid',
zip: '80828',
},
},
{
first_name: 'Nixie',
last_name: 'Languin',
dob: ISODate('2011-02-11'),
address: {
street: {
name: 'Kensington Ln.',
number: '33',
},
city: 'Zoofreid',
zip: '80829',
},
},
{
first_name: 'Anthony',
last_name: 'Apple',
dob: ISODate('2009-08-16'),
address: {
street: {
name: 'Flint Rd.',
number: '803',
},
city: 'Camden',
zip: '10832',
},
},
{
first_name: 'Rose',
last_name: 'Southby',
dob: ISODate('2011-03-03'),
address: {
street: {
name: 'Plainfield Dr.',
number: '4c',
},
city: 'Nambles',
zip: '38008',
},
},
{
first_name: 'Lain',
last_name: 'Singh',
dob: ISODate('2013-06-22'),
address: {
street: {
name: 'Plainfield Dr.',
number: '308',
},
city: 'Brighton',
zip: '18002',
},
},
])

上記のドキュメントを挿入したら、次のセクションに進んで単純な並べ替えについて学びましょう。

単一フィールドを並べ替える方法

MongoDBで結果を並べ替える基本的なアプローチは、クエリに.sort()メソッドを追加することです。.sort()メソッドは、並べ替えるフィールドと並べ替え方向を指定するドキュメントを引数として取ります。

結果を並べ替える最も基本的な方法は、昇順ソートを示す1の値を持つ列名を指定する単一のフィールドを定義したドキュメントを提供することです。

.find()の2番目の引数としてMongoDBプロジェクションを提供し、特定のフィールドのみを表示していることに注意してください。また、出力を読みやすくするために.pretty()メソッドを追加しています。

db.students
.find(
{},
{
_id: 0,
first_name: 1,
last_name: 1,
dob: 1,
}
)
.sort({
dob: 1,
})
.pretty()

上記のクエリは、生年月日順にデフォルトの昇順で学生を返します。

{
"first_name" : "Spencer",
"last_name" : "Burton",
"dob" : ISODate("2008-12-04T00:00:00Z")
}
{
"first_name" : "Anthony",
"last_name" : "Apple",
"dob" : ISODate("2009-08-16T00:00:00Z")
}
{
"first_name" : "Carol",
"last_name" : "Apple",
"dob" : ISODate("2010-10-30T00:00:00Z")
}
{
"first_name" : "Nixie",
"last_name" : "Languin",
"dob" : ISODate("2011-02-11T00:00:00Z")
}
{
"first_name" : "Rose",
"last_name" : "Southby",
"dob" : ISODate("2011-03-03T00:00:00Z")
}
{
"first_name" : "Lain",
"last_name" : "Singh",
"dob" : ISODate("2013-06-22T00:00:00Z")
}

順序を逆にするには、並べ替え列を1ではなく-1に設定します。

db.students
.find(
{},
{
_id: 0,
first_name: 1,
last_name: 1,
dob: 1,
}
)
.sort({
dob: -1,
})
.pretty()
{
"first_name" : "Lain",
"last_name" : "Singh",
"dob" : ISODate("2013-06-22T00:00:00Z")
}
{
"first_name" : "Rose",
"last_name" : "Southby",
"dob" : ISODate("2011-03-03T00:00:00Z")
}
{
"first_name" : "Nixie",
"last_name" : "Languin",
"dob" : ISODate("2011-02-11T00:00:00Z")
}
{
"first_name" : "Carol",
"last_name" : "Apple",
"dob" : ISODate("2010-10-30T00:00:00Z")
}
{
"first_name" : "Anthony",
"last_name" : "Apple",
"dob" : ISODate("2009-08-16T00:00:00Z")
}
{
"first_name" : "Spencer",
"last_name" : "Burton",
"dob" : ISODate("2008-12-04T00:00:00Z")
}

追加フィールドで並べ替える方法

MongoDBは、主並べ替えフィールドに重複が含まれる場合に、追加フィールドを使用して並べ替えを制御できます。これを行うには、sort()関数に渡すドキュメント内に、追加フィールドとその並べ替え順序を渡します。

例えば、studentドキュメントをlast_nameで並べ替えると、その1つのフィールドに基づいて学生のアルファベット順リストを取得できます。

db.students
.find(
{},
{
_id: 0,
first_name: 1,
last_name: 1,
}
)
.sort({
last_name: 1,
})
.pretty()
{ "first_name" : "Carol", "last_name" : "Apple" }
{ "first_name" : "Anthony", "last_name" : "Apple" }
{ "first_name" : "Spencer", "last_name" : "Burton" }
{ "first_name" : "Nixie", "last_name" : "Languin" }
{ "first_name" : "Lain", "last_name" : "Singh" }
{ "first_name" : "Rose", "last_name" : "Southby" }

しかし、「Apple」という姓の学生が2人おり、名も考慮すると、返される順序はアルファベット順ではありません。

これを修正するには、first_nameを補助並べ替えフィールドとして使用できます。

db.students
.find(
{},
{
_id: 0,
first_name: 1,
last_name: 1,
}
)
.sort({
last_name: 1,
first_name: 1,
})
.pretty()
{ "first_name" : "Anthony", "last_name" : "Apple" }
{ "first_name" : "Carol", "last_name" : "Apple" }
{ "first_name" : "Spencer", "last_name" : "Burton" }
{ "first_name" : "Nixie", "last_name" : "Languin" }
{ "first_name" : "Lain", "last_name" : "Singh" }
{ "first_name" : "Rose", "last_name" : "Southby" }

その追加指定の後、結果は名前に期待される従来のアルファベット順に一致します。

埋め込みドキュメントフィールドを使用して並べ替える方法

MongoDBは、埋め込みドキュメントに含まれる値に基づいて結果を並べ替えることもできます。これを行うには、ドット記法を使用して、埋め込みドキュメント内の適切なフィールドにドリルダウンします。

例えば、各ドキュメント内のaddressの一部である居住地cityに基づいて、studentデータを並べ替えることができます。ドット記法を使用する際は、フィールド名が正しく解釈されるように引用符で囲む必要があることに注意してください。

db.students
.find(
{},
{
_id: 0,
first_name: 1,
last_name: 1,
'address.city': 1,
}
)
.sort({
'address.city': 1,
})
.pretty()
{
"first_name" : "Lain",
"last_name" : "Singh",
"address" : {
"city" : "Brighton"
}
}
{
"first_name" : "Carol",
"last_name" : "Apple",
"address" : {
"city" : "Camden"
}
}
{
"first_name" : "Anthony",
"last_name" : "Apple",
"address" : {
"city" : "Camden"
}
}
{
"first_name" : "Rose",
"last_name" : "Southby",
"address" : {
"city" : "Nambles"
}
}
{
"first_name" : "Spencer",
"last_name" : "Burton",
"address" : {
"city" : "Zoofreid"
}
}
{
"first_name" : "Nixie",
"last_name" : "Languin",
"address" : {
"city" : "Zoofreid"
}
}

これをさらに並べ替えフィールドと組み合わせることで、結果を思いどおりに並べ替えることができます。

db.students
.find(
{},
{
_id: 0,
first_name: 1,
last_name: 1,
'address.city': 1,
'address.street': 1,
}
)
.sort({
'address.city': 1,
'address.street.name': 1,
'address.street.number': 1,
last_name: 1,
first_name: 1,
})
.pretty()

この例では、以下のフィールドを順に並べ替えました。

  • 道路名
  • 番地

クエリの結果は次のようになります。

{
"first_name" : "Lain",
"last_name" : "Singh",
"address" : {
"street" : {
"name" : "Plainfield Dr.",
"number" : "308"
},
"city" : "Brighton"
}
}
{
"first_name" : "Anthony",
"last_name" : "Apple",
"address" : {
"street" : {
"name" : "Flint Rd.",
"number" : "803"
},
"city" : "Camden"
}
}
{
"first_name" : "Carol",
"last_name" : "Apple",
"address" : {
"street" : {
"name" : "Flint Rd.",
"number" : "803"
},
"city" : "Camden"
}
}
{
"first_name" : "Rose",
"last_name" : "Southby",
"address" : {
"street" : {
"name" : "Plainfield Dr.",
"number" : "4c"
},
"city" : "Nambles"
}
}
{
"first_name" : "Spencer",
"last_name" : "Burton",
"address" : {
"street" : {
"name" : "Edgecombe St.",
"number" : "2083b"
},
"city" : "Zoofreid"
}
}
{
"first_name" : "Nixie",
"last_name" : "Languin",
"address" : {
"street" : {
"name" : "Kensington Ln.",
"number" : "33"
},
"city" : "Zoofreid"
}
}

ここで、並べ替えに使用するフィールドが、プロジェクションで提供するフィールドのサブセットである必要はないことにも言及しておきます。

例えば、以下の入力により、全く同じ順序で学生名のみを返すことができます。

db.students
.find(
{},
{
_id: 0,
first_name: 1,
last_name: 1,
}
)
.sort({
'address.city': 1,
'address.street.name': 1,
'address.street.number': 1,
last_name: 1,
first_name: 1,
})
.pretty()

クエリは以下のデータを返します。

{ "first_name" : "Lain", "last_name" : "Singh" }
{ "first_name" : "Anthony", "last_name" : "Apple" }
{ "first_name" : "Carol", "last_name" : "Apple" }
{ "first_name" : "Rose", "last_name" : "Southby" }
{ "first_name" : "Spencer", "last_name" : "Burton" }
{ "first_name" : "Nixie", "last_name" : "Languin" }

結果を前のクエリと比較すると、ドキュメントが同じ順序で返されたことを確認できます。

まとめ

この記事では、sort()メソッドを使用してMongoDBがクエリの結果をどのように並べ替えるかを制御する方法について説明しました。単一フィールドの並べ替え、優先順位による複数フィールドの並べ替え、並べ替え順序の変更、および埋め込みドキュメントフィールドに基づく並べ替えについて解説しました。

ドキュメントの照合結果の制限といった機能と組み合わせることで、並べ替えにより、ドキュメントとフィールドが互いにどのように比較され、どのように返されるかを正確に制御できます。これらの機能に慣れることは、より良いクエリを作成し、データをより利用しやすい状態で返すのに役立ちます。

著者について
Justin Ellingwood

ジャスティン・エリングウッド

ジャスティンは2013年以来、データベース、Linux、インフラストラクチャ、開発者ツールについて執筆しています。現在はベルリンで妻と2匹のウサギと暮らしています。通常、三人称で書く必要がないため、関係者全員にとって安心です。
© . All rights reserved.