2015/11/23

如何在 CentOS 安裝 MongoDB

MongoDB 屬於 NoSQL Database 中的文件資料庫這種類型,可以儲存 XML, JSON 或是其他格式的文件資料,這些資料都是 self-describing 的,也就是說文件之間並不需要完全一樣,換句話說,在更新 schema 時,並不需要修改既有的資料。

依照這個網頁的說明 Install MongoDB on Red Hat Enterprise or CentOS Linux,就可以把 mongodb 裝好。

Packages

  1. mongodb-org
    這是自動安裝其他四個 packages 的 metapackage
  2. mongodb-org-server
    包含 mongod daemon、configurations以及 init scripts
  3. mongodb-org-mongos
    包含 mongos daemon
  4. mongodb-org-shell
    包含 mongo shell
  5. mongodb-org-tools
    包含以下的 MongoDB 工具: mongoimport bsondump, mongodump, mongoexport, mongofiles, mongooplog, mongoperf, mongorestore, mongostat, and mongotop

mongod 的 service script 在 /etc/init.d/mongod

設定檔在 /etc/mongod.conf

資料存放在 /var/lib/mongo

log 存放在 /var/log/mongodb

vi /etc/yum.repos.d/mongodb-org-3.0.repo

[mongodb-org-3.0]
name=MongoDB Repository
baseurl=https://repo.mongodb.org/yum/redhat/$releasever/mongodb-org/3.0/x86_64/
gpgcheck=0
enabled=1

用以下指令安裝並啟動 mongodb

yum install -y mongodb-org
service mongod start

在 /var/log/mongodb/mongod.log 裡面看到這一行,基本上就是把 mongodb 環境安裝好了。

[initandlisten] waiting for connections on port 27017

簡單的 DB 測試

執行 mongo 就會直接連接到 test 這個 database

show dbs 是顯示所有資料庫, show collections 是顯示資料庫中的 collections,相當於關聯式資料庫的 table

> show dbs
local  0.078GB
> show dbs;
local  0.078GB
> show collections;

切換到 mydatabase 資料庫

> use mydatabase;
switched to db mydatabase
> db
mydatabase
  1. insert 新增
    建立一個 post 文件,將 post 放進

    > post = { "title": "今日天氣", "content": "晴朗", "date": new Date()}
    {
     "title" : "今日天氣",
     "content" : "晴朗",
     "date" : ISODate("2015-11-05T08:33:54.761Z")
    }
    > db.blog.insert(post)
    WriteResult({ "nInserted" : 1 })
    
  2. find 查詢
    以 find 取得所有資料

    > db.blog.find()
    { "_id" : ObjectId("563b147db835798ae60f4bae"), "title" : "今日天氣", "content" : "晴朗", "date" : ISODate("2015-11-05T08:33:54.761Z") }
    
  3. update 修改
    先修改剛剛的 post 資料,然後用 update 更新到資料庫中。

    > post.comment = ["Great!"]
    [ "Great!" ]
    > post
    {
     "title" : "今日天氣",
     "content" : "晴朗",
     "date" : ISODate("2015-11-05T08:33:54.761Z"),
     "comment" : [
         "Great!"
     ]
    }
    > db.blog.update({title: "今日天氣"}, post)
    WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
    > db.blog.find()
    { "_id" : ObjectId("563b147db835798ae60f4bae"), "title" : "今日天氣", "content" : "晴朗", "date" : ISODate("2015-11-05T08:33:54.761Z"), "comment" : [ "Great!" ] }
    
  4. remove 刪除
    以 remove 刪除資料

    > db.blog.remove({title: "今日天氣"});
    WriteResult({ "nRemoved" : 1 })
    > db.blog.find();
    

如何用 R 語言連接 MongoDB

先在 mongodb 重新新增兩筆資料

# mongo
> post = { "title": "今日天氣", "content": "晴朗", "date": new Date()}
> db.blog.insert(post)

> post2 = { "title": "明日天氣", "content": "陰天", "date": new Date()}
> db.blog.insert(post2)

在 R 語言的界面中,依照以下的過程進行測試

  1. 安裝 rmongodb 套件

    > install.packages("rmongodb")
    
  2. 使用 rmongodb library

    > library(rmongodb)
    
  3. 建立 mongodb 連線

    > mongo <- mongo.create(host="192.168.1.11" , db="test", username="", password="")
    > dbns <- mongo.get.database.collections(mongo, db="test")
    
  4. 建立查詢條件,並以 find 查詢資料

    > query <- '{ "title": { "$exists": true }, "content": { "$exists": true } }'
    > 
    > cur <- mongo.find(mongo, dbns, query=query)
    
  5. 將 cursor 結果轉換成 data.frame

     > title <- content <- date <- NULL
     > while (mongo.cursor.next(cur)) {
     +     value <- mongo.cursor.value(cur)
     +     title <- rbind(title, mongo.bson.value(value, 'title'))
     +     content <- rbind(content, mongo.bson.value(value, 'content'))
     +  
     +     date <- rbind(date, mongo.bson.value(value, 'date'))
     + }
     > 
     > posts <- data.frame(title=title, content=content, date=date)
    
     > posts
            title           content       date
     1 隞憭拇除 \xe6\xe6\x9c\x97 1446714342
     2 \xe6\x98憭拇除       \xe9憭\xa9 1446715746
    
  6. 中文顯示有問題
    在產生 data.frame 之前,必須先設定 UTF-8 Encoding

    > Encoding(title)="UTF-8"
    > 
    > Encoding(content)="UTF-8"
    > 
    > posts <- data.frame(title=title, content=content, date=date)
    > 
    > posts
      title content       date
    1 今日天氣    晴朗 1446714342
    2 明日天氣    陰天 1446715746
    

濃縮所有測試過程的指令如下

install.packages("rmongodb")
library(rmongodb)
mongo <- mongo.create(host="192.168.1.11" , db="test", username="", password="")
dbns <- mongo.get.database.collections(mongo, db="test")
query <- '{ "title": { "$exists": true }, "content": { "$exists": true } }'

cur <- mongo.find(mongo, dbns, query=query)

title <- content <- date <- NULL

while (mongo.cursor.next(cur)) {
value <- mongo.cursor.value(cur)
title <- rbind(title, mongo.bson.value(value, 'title'))
content <- rbind(content, mongo.bson.value(value, 'content'))
date <- rbind(date, mongo.bson.value(value, 'date'))
}
Encoding(title)="UTF-8"
Encoding(content)="UTF-8"
posts <- data.frame(title=title, content=content, date=date)
posts

在 rmongodb 寫入中文也會遇到編碼的問題,參考 R實踐之中文編碼轉換,必須先用 iconv 先將中文字串轉碼。