🙌

ひとりMongoDB University 12/02 - インデクシングとアグリゲーション基本(2)

2020/12/02に公開

この記録は、アドベントカレンダー形式の、MongoDB Universityの学習コースの記録、2日目になります!
引き続き、M001のコースです。12/15までに終わらせるのを目標にしています。
詳細はこちら。

Chapter 5: Indexing and Aggregation Pipeline

カーソルメソッド / sort() and limit()

本日は sort() and limit() の動画から。
$group というアグリゲーションの関数とは違い、こちらはカーソルメソッド。
すでに出てきている、pretty() や count() と同じ扱いになる。

  • sort({ ソートの対象: ソートのオーダー指定 (1 or -1) })

# zipsコレクションからデータ抽出。
# pop属性に対して昇順でソートして、最初の1つを返す
db.zips.find().sort({ "pop": 1 }).limit(1)
{ _id: ObjectID("5c8eccc1caa187d17ca6eea3"),
  city: 'ALLEN',
  zip: '36419',
  loc: { y: 31.624266, x: 87.66746 },
  pop: 0,  # 昇順なので少ない順。0もある
  state: 'AL' }


# 降順の場合は -1 がreverseの意味
db.zips.find().sort({ "pop": -1 }).limit(1)
{ _id: ObjectID("5c8eccc1caa187d17ca7044d"),
  city: 'CHICAGO',
  zip: '60623',
  loc: { y: 41.849015, x: 87.7157 },
  pop: 112047,  # 人口の多い順
  state: 'IL' }

# カーソルメソッドの位置を変えてみる
# 1件だけ抽出してからソート(降順)
# 結果は同じ
db.zips.find().limit(1).sort({ "pop": -1 })
{ _id: ObjectID("5c8eccc1caa187d17ca7044d"),
  city: 'CHICAGO',
  zip: '60623',
  loc: { y: 41.849015, x: 87.7157 },
  pop: 112047,
  state: 'IL' }

ポイント

  • MongoDBは順番指定がなければ limit(N) 指定での抽出はオーダーは保証されない
  • sort() が利用される場合は、カーソル関数の順番に関係なく、ソートが先に処理される
    • xxxx.find().sort().limit(10) = xxxx.find().limit(10).sort()

MongoDB Compassを使ってのデータ確認や、Mongo Shellでの書き方をチェック。

MongoDB Compassでのデータ確認

Quiz 1: sort() and limit()

Problem:
Which of the following commands will return the name and founding year for the 5 oldest companies in the sample_training.companies collection?
companiesコレクションのなかから設立年が古い潤に5つ抽出するにはどれ?


# まず一件確認

use sample_training
db.companies.findOne()

....

# founded_year を使えばよさそう
db.companies.find().sort({ 'founded_year': 1 }).limit(5)

# fonded_year がnullのものが先にきてしまう!
# 明示的に数値が入っている(nullじゃない)ものを取り出す!

db.companies.find({ "founded_year": { "$ne": null }},
  { "name": 1, "founded_year": 1 }
).sort({ "founded_year": 1 }).limit(5)


# もしくはこれ(sortの位置は問わない)
db.companies.find({ "founded_year": { "$ne": null }},
  { "name": 1, "founded_year": 1 }
).limit(5).sort({ "founded_year": 1 })

Quiz 2: sort() and limit()

Problem:
In what year was the youngest bike rider from the sample_training.trips collection born?


use sample_training
# これだと birth yearが'' も含まれる
db.trips.find().sort( { 'birth year': -1 }).limit(1)

# これでどう?
db.trips.find({ "birth year": { "$ne": '' }}, { 'birth year': 1 }).sort( { 'birth year': -1 }).limit(1)
{ _id: ObjectID("572bb8222b288919b68ac17d"),
  'birth year': 1999 }

本日の記録

朝活分です!

動画1つと問題2つ進みました

きょうのzenn

2日目なので、slugも今日の分に。

zenn-contents $ npx zenn new:article --slug 20201202-mongodb-univ
📄20201201-mongodb-univ.md created.

明日もがんばろう!

Discussion