第 10 章 - 資料庫

MongoDB 文件型 JSON 資料庫

MongoDB -- 安裝與啟動

下載點: https://www.mongodb.org/downloads

下載完成後使用『下一步』大法即可完成安裝。

安裝完成之後,在 windows 下必須設定系統路徑,我的路徑在: 『C:\Program Files\MongoDB\Server\3.0\bin』 當中。

接著請啟動命令列,然後建立資料庫路徑 /db/mongodb/ ,接著輸入下列指令。

D:\db>mongod --dbpath /db/mongodb

此時 mongodb 伺服器就會啟動完成。

D:\db>mongo
MongoDB shell version: 3.0.2
connecting to: test

接著您就可以使用指令進行『新增/修改/刪除/查詢』了。

新增操作

參考: http://www.w3cschool.cc/mongodb/mongodb-insert.html

> db.user.insert({user:"CCC", password:"123"})
WriteResult({ "nInserted" : 1 })
> db.user.find()
{ "_id" : ObjectId("55486b1327403e89a3cc397a"), "user" : "ccc", "password" : "123" }
> db.user.insert({user:"snoopy", password:"321"})
WriteResult({ "nInserted" : 1 })
> db.user.find()
{ "_id" : ObjectId("55486b1327403e89a3cc397a"), "user" : "ccc", "password" : "123" }
{ "_id" : ObjectId("55487073434ed6d677f8454d"), "user" : "snoopy", "password" : "321" }

修改操作

參考: http://www.w3cschool.cc/mongodb/mongodb-update.html

> db.user.update({"user":"snoopy"}, {"user":"snoopy", "password":"snoopy321"})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.user.find()
{ "_id" : ObjectId("55486b1327403e89a3cc397a"), "user" : "ccc", "password" : "123" }
{ "_id" : ObjectId("55487073434ed6d677f8454d"), "user" : "snoopy", "password" : "snoopy321" }

刪除操作

參考: http://www.w3cschool.cc/mongodb/mongodb-remove.html

> db.user.find()
{ "_id" : ObjectId("55486b1327403e89a3cc397a"), "user" : "ccc", "password" : "123" }
{ "_id" : ObjectId("55487073434ed6d677f8454d"), "user" : "snoopy", "password" : "snoopy321" }
> db.user.remove({user:"ccc"})
WriteResult({ "nRemoved" : 1 })
> db.user.find()
{ "_id" : ObjectId("55487073434ed6d677f8454d"), "user" : "snoopy", "password" : "snoopy321" }

查詢操作

參考: http://www.w3cschool.cc/mongodb/mongodb-update.html

> db.user.insert({user:"garfield", password:"cookie"})
WriteResult({ "nInserted" : 1 })
> db.user.find()
{ "_id" : ObjectId("55487073434ed6d677f8454d"), "user" : "snoopy", "password" : "snoopy321" }
{ "_id" : ObjectId("55487d09434ed6d677f8454e"), "user" : "garfield", "password": "cookie" }
> db.user.find({user:"garfield"})
{ "_id" : ObjectId("55487d09434ed6d677f8454e"), "user" : "garfield", "password": "cookie" }
> db.user.find({user:"snoopy"})
{ "_id" : ObjectId("55487073434ed6d677f8454d"), "user" : "snoopy", "password" :"snoopy321" }

條件式查詢

參考: http://www.w3cschool.cc/mongodb/mongodb-operators.html

> db.users.find({age :{$gt : 8}})
{ "_id" : ObjectId("55487ecd3c69cbdeba209fb3"), "name" : "ccc", "age" : 45, "password" : "321" }
{ "_id" : ObjectId("55487eed3c69cbdeba209fb5"), "name" : "garfield", "age" : 9,"password" : "garfield123" }
> db.users.find()
{ "_id" : ObjectId("55487ecd3c69cbdeba209fb3"), "name" : "ccc", "age" : 45, "password" : "321" }
{ "_id" : ObjectId("55487ede3c69cbdeba209fb4"), "name" : "snoopy", "age" : 5, "password" : "snoopy123" }
{ "_id" : ObjectId("55487eed3c69cbdeba209fb5"), "name" : "garfield", "age" : 9, "password" : "garfield123" }
> db.users.find().limit(2)
{ "_id" : ObjectId("55487ecd3c69cbdeba209fb3"), "name" : "ccc", "age" : 45, "password" : "321" }
{ "_id" : ObjectId("55487ede3c69cbdeba209fb4"), "name" : "snoopy", "age" : 5, "password" : "snoopy123" }
> db.users.find().limit(2).skip(1)
{ "_id" : ObjectId("55487ede3c69cbdeba209fb4"), "name" : "snoopy", "age" : 5, "password" : "snoopy123" }
{ "_id" : ObjectId("55487eed3c69cbdeba209fb5"), "name" : "garfield", "age" : 9,"password" : "garfield123" }

排序與索引

> db.users.find().sort({age:1})
{ "_id" : ObjectId("55487ede3c69cbdeba209fb4"), "name" : "snoopy", "age" : 5, "password" : "snoopy123" }
{ "_id" : ObjectId("55487eed3c69cbdeba209fb5"), "name" : "garfield", "age" : 9,"password" : "garfield123" }
{ "_id" : ObjectId("55487ecd3c69cbdeba209fb3"), "name" : "ccc", "age" : 45, "password" : "321" }
> db.users.find().sort({age:-1})
{ "_id" : ObjectId("55487ecd3c69cbdeba209fb3"), "name" : "ccc", "age" : 45, "password" : "321" }
{ "_id" : ObjectId("55487eed3c69cbdeba209fb5"), "name" : "garfield", "age" : 9,"password" : "garfield123" }
{ "_id" : ObjectId("55487ede3c69cbdeba209fb4"), "name" : "snoopy", "age" : 5, "password" : "snoopy123" }
> db.users.ensureIndex({name:1})
{
        "createdCollectionAutomatically" : false,
        "numIndexesBefore" : 1,
        "numIndexesAfter" : 2,
        "ok" : 1
}

離開

> quit()

D:\db>

日期與時間操作

> db.filelog.insert({path:'wd.html', time:new Date()})
WriteResult({ "nInserted" : 1 })
> db.filelog.find()
{ "_id" : ObjectId("571d78c179eb77457f34a8b5"), "path" : "wd.html", "time" : ISO
Date("2016-04-25T01:54:09.026Z") }
>

使用程式存取 MongoDB

您若要在 node.js 當中存取 mongoDB 的資料,必須先用 npm 安裝 mongoDB 的套件。

npm install mongodb

mongodb 的官方 node.js API 說明文件位於下列網址:

程式範例: mongotest.js

參考: https://mongodb.github.io/node-mongodb-native/api-articles/nodekoarticle1.html

var MongoClient = require('mongodb').MongoClient;

MongoClient.connect("mongodb://localhost:27017/examdb", function(err, db) {
  if(err) { return console.dir(err); }

  var collection = db.collection('Q');
  var docs = [{ type:"word", q:"he=他"}, { type:"word", q:"she=她"}, { type:"word", q:"it=它"} ];

  collection.insert(docs, {w:1}, function(err, result) { // success!

    collection.find().toArray(function(err, items) {
        console.log("items=%j", items);
        db.close();
    });
  });
});

執行結果:

nqu-192-168-61-142:KoaExam mac020$ node mongotest
items=[{"_id":"5716e82ea6c866eb02ffe700","type":"word","q":"he=他"},{"_id":"5716e82ea6c866eb02ffe701","type":"word","q":"she=她"},{"_id":"5716e82ea6c866eb02ffe702","type":"word","q":"it=它"}]

採用 yield 的寫法

檔案: comongotest.js

var co = require("co");

var MongoClient = require('mongodb').MongoClient;

co(function*() {
  var db = yield MongoClient.connect('mongodb://localhost:27017/examdb');
  var collection = db.collection('Q');
  var result = yield collection.insertMany([{ type:"word", q:"he=他"}, { type:"word", q:"she=她"}, { type:"word", q:"it=它"} ], {w:1});
  var items = yield collection.find().toArray();
  console.log("items=%j", items);
  var result = yield db.close();
});

執行結果

NQU-192-168-60-101:js csienqu$ node comongotest
items=[{"_id":"57201788d3c8212f034d9479","type":"word","q":"he=他"},{"_id":"57201788d3c8212f034d947a","type":"word","q":"she=她"},{"_id":"57201788d3c8212f034d947b","type":"word","q":"it=它"}]

資料庫管理操作

  • show dbs // 顯示資料庫
  • use // 切換使用
  • db.getCollectionNames() // 取得此資料庫中的所有集合, node: db.listCollections()
> show dbs
bible      0.000GB
examdb     0.000GB
fdbserver  0.000GB
local      0.000GB
> db.getCollectionNames()
[ "book" ]
> use examdb
switched to db examdb
> db.getCollectionNames()
[ "Q" ]
> use fdbserver
switched to db fdbserver
> db.getCollectionNames()
[ "filelog" ]
>

不重複的新增

Don't use insert.

Use update with upsert=true. Update will look for the document that matches your query, then it will modify the fields you want and then, you can tell it upsert:True if you want to insert if no document matches your query.

db.collection.update(
   <query>,
   <update>,
  {
    upsert: <boolean>,
     multi: <boolean>,
    writeConcern: <document>
   }
  )
So, for your example, you could use something like this:

db.collection.update(doc, doc, {upsert:true})

全文檢索

D:\>mongo bible
MongoDB shell version: 3.2.5
connecting to: bible
Server has startup warnings:
...
> db.book.find()
> db.book.insert({title:"chapter1", content:"chapter 1 . This is chapter 1"})
WriteResult({ "nInserted" : 1 })
> db.book.insert({title:"chapter2", content:"chapter 2 . This is chapter 2"})
WriteResult({ "nInserted" : 1 })
> db.book.find()
{ "_id" : ObjectId("5844c8d8ee7f73b610e9747f"), "title" : "chapter1", "content"
: "chapter 1 . This is chapter 1" }
{ "_id" : ObjectId("5844c8e2ee7f73b610e97480"), "title" : "chapter2", "content"
: "chapter 2 . This is chapter 2" }
> db.book.createIndex({"$**":"text"}, {name:"FullTextIndex"})
{
        "createdCollectionAutomatically" : false,
        "numIndexesBefore" : 1,
        "numIndexesAfter" : 2,
        "ok" : 1
}
> db.book.find({title:"chapter1"})
{ "_id" : ObjectId("5844c8d8ee7f73b610e9747f"), "title" : "chapter1", "content"
: "chapter 1 . This is chapter 1" }
> db.book.find({title:"chapter1", $text:{$search:"chapter"}})
{ "_id" : ObjectId("5844c8d8ee7f73b610e9747f"), "title" : "chapter1", "content"
: "chapter 1 . This is chapter 1" }
> db.book.find({$text:{$search:"chapter"}})
{ "_id" : ObjectId("5844c8e2ee7f73b610e97480"), "title" : "chapter2", "content"
: "chapter 2 . This is chapter 2" }
{ "_id" : ObjectId("5844c8d8ee7f73b610e9747f"), "title" : "chapter1", "content"
: "chapter 1 . This is chapter 1" }

匯入匯出資料

Mongo includes a mongoexport utility which can dump a collection:

mongoexport -d <database> -c <collection_name>
Use the '-o' flag to write the output to file, otherwise standard output is used. This utility uses the native libmongoclient and is likely the fastest method.
$ mongoimport -d mydb -c things --type csv --file locations.csv --headerline

安全性議題

啟動帳號密碼機制

1 - Start MongoDB without access control.

mongod --port 27017 --dbpath /data/db1

2 - Connect to the instance

mongo --port 27017

3 - Create the user administrator.

use admin
db.createUser(
  {
    user: "myUserAdmin",
    pwd: "abc123",
    roles: [ { role: "userAdminAnyDatabase", db: "admin" } ]
  }
)

4 - Re-start the MongoDB instance with access control.

var MongoClient = require('mongodb').MongoClient,
  f = require('util').format,
  assert = require('assert');

var user = encodeURIComponent('dave');
var password = encodeURIComponent('abc123');
var authMechanism = 'DEFAULT';
var authSource = 'myproject';

// Connection URL
var url = f('mongodb://%s:%s@localhost:27017?authMechanism=%s&authSource=',
  user, password, authMechanism, authSource);

// Use connect method to connect to the Server
MongoClient.connect(url, function(err, db) {
  assert.equal(null, err);
  console.log("Connected correctly to server");

  db.close();
});

5 - Connect and authenticate as the user administrator.

mongo --port 27017 -u "myUserAdmin" -p "abc123" --authenticationDatabase "admin"
To authenticate after connecting

Connect the mongo shell to the mongod:

mongo --port 27017
Switch to the authentication database (in this case, admin), and use db.auth(<username>, <pwd>) method to authenticate:

use admin
db.auth("myUserAdmin", "abc123" )

SSL : https://docs.mongodb.com/v3.2/tutorial/configure-ssl/

mongod --sslMode requireSSL --sslPEMKeyFile <pem>

習題

  1. 請安裝好 mongodb 資料庫,並用 mongod 啟動伺服器之後,用 mongo 指令開始新增資料,並且玩玩資料庫《新增、修改、刪除、查詢》的動作,直到你能熟練地進行這些操作為止。
  2. 請建立一個自己想要用的資料庫 (像是通訊錄、字典....)等等,然後用編輯器(像是 notepad++) 編寫一堆資料後,寫程式將資料倒進該資料庫中!

參考文獻

results matching ""

    No results matching ""