使用 MongoDB 的 find() 及 aggregate()
db.collection.find() 官方的說明文件在 https://docs.mongodb.com/manual/reference/method/db.collection.find/。
先滙入 https://github.com/ozlerhakan/mongodb-json-files 裡 datasets 的 books.json 到 test 資料庫:
$ mongoimport --db test --collection books --file ~/downloads/books.json
2020-04-26T08:21:27.742+0800 connected to: mongodb://localhost/
2020-04-26T08:21:29.561+0800 431 document(s) imported successfully. 0 document(s) failed to import.
先來看篩選(filter),以下是使用 mongo shell 的操作:
> use test
> db.books.findOne() # 先找出第一筆查看大概的結構
{
"_id" : 3,
"title" : "Specification by Example",
"isbn" : "1617290084",
"pageCount" : 0,
"publishedDate" : ISODate("2011-06-03T07:00:00Z"),
"thumbnailUrl" : "https://s3.amazonaws.com/AKIAJC5RLADLUMVRPFDQ.book-thumb-images/adzic.jpg",
"status" : "PUBLISH",
"authors" : [
"Gojko Adzic"
],
"categories" : [
"Software Engineering"
]
}
> db.books.find({isbn: 1617290084}) #找不到資料,型別不對
> db.books.find({isbn: '1617290084'}) #找到第一筆
# categoriries 為陣列,使用字串篩選時,結果會是陣列中有包含該字串的資料都會找出來
> db.books.find({categories: 'Software Engineering'})
# 計算個數
> db.books.find({categories: 'Software Engineering'}).count()
# 只查看前兩筆
> db.books.find({categories: 'Software Engineering'}).limit(2)
# 跳過 3 筆,取 5 筆
> db.books.find({categories: 'Software Engineering'}).skip(3).limit(5)
# categoriries 為陣列,使用陣列篩選時,值必須相同(序順也必須一樣)
> db.books.find({categories: ['Software Engineering']})
# 以下搜尋的結果會不同
> db.books.find({categories: ['Java', 'Software Engineering']})
> db.books.find({categories: ['Software Engineering', 'Java']})
# 陣列中特定位置的值
> db.books.find({'categories.1': 'Java'})
> db.books.find({'categories.1': 'Software Engineering'})
# 若是物件也是類似的作法 {'name.first': 'Bill'}
# $all 同時包含(AND運算,不管順序)
> db.books.find({categories: { $all: ['Software Engineering', 'Java']}})
# $in 包含任一個(OR運算)
> db.books.find({categories: { $in: ['Software Engineering', 'XML']}})
# $nin 不包含任一個
> db.books.find({categories: {$nin: ['Java']}}).count()
# 包含 'Software Engineering',但不包含 'Java'
> db.books.find({categories: { $in: ['Software Engineering'], $nin: ['Java']}})
# 使用 Regular Expression
> db.books.find({categories: /Software/}) # 陣列中任一符合
> db.books.find({title: /Practice/}) # 字串
# 沒有某個欄位
> db.books.find({publishedDate: {$exists: false} }).count()
# 有某個欄位
> db.books.find({publishedDate: {$exists: true} }).count()
# 某個物件的值大於、等於、小於、不等於、大於等於、小於等於、範圍
> db.inventory.find({'size.h': {$gt: 10}})
> db.inventory.find({'size.h': {$eq: 10}})
> db.inventory.find({'size.h': {$lt: 10}})
> db.inventory.find({'size.h': {$ne: 10}})
> db.inventory.find({'size.h': {$gte: 10}})
> db.inventory.find({'size.h': {$lte: 10}})
> db.inventory.find({'size.h': {$gt: 9, $lt: 15}})
# 日期
> db.books.find({publishedDate: {$gte: new Date('2014-01-01')} })
投射(project),就是要看哪些欄位,要看給 1,不看給 0。 可以使用 find() 的第二個參數,或使用 aggregate()。
# 只顯示 title, _id 預設是顯示的
# 使用 find() 的第二個參數
> db.books.find({}, {title:1, _id:0})
> db.books.find({publishedDate: {$gte: new Date('2014-01-01')} }, {title:1, publishedDate:1})
# 使用 aggregate()
> db.books.aggregate({$project: {title:1, _id:0}})
> db.books.aggregate([{
$match: {
publishedDate: { $gte: new Date('2014-01-01') }
}
},{
$project: {title:1, publishedDate:1}
}])
# 不顯示設定的欄位,使用 find() 的第二個參數
> db.books.find({}, {shortDescription: 0, longDescription: 0}).limit(5)
# 不顯示設定的欄位,使用 aggregate()
> db.books.aggregate([{$project: {shortDescription: 0, longDescription: 0}}, {$limit: 5}])
排序(sort),依欄位,升冪給 1,降冪給 -1。
> db.books.aggregate([{
$match: {
categories: 'XML'
}
}, {
$project: {title:1, publishedDate:1}
}, {
$sort: {publishedDate: -1}
}])
複雜的操作都落在 aggregate() 上。
沒有留言:
張貼留言