mongodb 踩坑記錄


Map-Reduce

Map-Reduce 是 mongodb 處理批量數據的大殺器,凡是數據量大並且定時處理能滿足需求的,都可以試着扔給 mongodb,讓它去 Map-Reduce。

以下截取自文檔的圖,可以清楚的說明 Map-Reduce 的執行過程。先看圖:

MapReduce

回答問題,Map-Reduce 的執行過程是先 map 然后 reduce 么?

是?恭喜入坑!而且是自己挖坑自己填。仔細再看一遍上文的圖,看到那個灰色的箭頭了?不是每次 map 都有 reduce 的!

如果 map 的結果不是數組,mongodb 就不會執行 reduce。很合理的處理邏輯。

然后,只有入過坑才能意識到自己挖的坑:對於 map 到的數據,如果在 reduce 時希望做統一的處理,一定會發現數據結果是不完整的。

mgo 時間

mgo 是 golang 的 mongodb driver。

首先,構建測試程序。

package main

import (
  "log"
  "time"

  "gopkg.in/mgo.v2"
  . "gopkg.in/mgo.v2/bson"
)

type TestTime struct {
  Id           ObjectId "_id"
  CreationTime time.Time
}

func main() {
  session, err := mgo.Dial("127.0.0.1")
  if err != nil {
    log.Fatalln("Fatal error:", err.Error())
  }

  defer session.LogoutAll()
  defer session.Close()

  tc := session.DB("test").C("testtime")

  t := time.Now()
  id := NewObjectId()

  test := TestTime{
    Id:           id,
    CreationTime: t,
  }

  tc.Insert(test)

  var testTime TestTime
  tc.FindId(id).One(&testTime)

  log.Println(t)

  log.Println(t == testTime.CreationTime)
}

UTC

執行測試程序,查看 mongodb 數據

/* 0 */
{
    "_id" : ObjectId("548d0b3194e33700f5ffaba9"),
    "creationtime" : ISODate("2014-12-14T03:59:45.123Z")
}

時間已經是 UTC 了,沒有必要 time.Now().UTC(),當然,執行下 .UTC() 代碼看起來更明確,也耗費不了多少 CPU,因為,.UTC() 僅僅是賦值時間的 location,其源碼如下:

func (t Time) UTC() Time{
  t.loc = UTC
  return t
}

精度

mgo 直接以 time.Time 類型插入 mongodb 的時間精度與 time.Now() 的時間精度是不同的:

  • mgo 精度為 ms
  • time.Now() 精度為 ns2014-12-14 11:59:45.123670247 +0800 CST

所以,上文 log.Println(t == testTime.CreationTime) 打印結果是 false

_id 索引

_id 是 mongodb 每個文檔必備字段,而且是默認索引,就是說不管你用不用,它都會建立索引並占用存儲空間。

在設計存儲結構時,只要能保證唯一性,即可將其作為 _id,例如:

{
    "_id" : {
        "nickname" : "busyStone",
        "index" : 1
    },
    "creationtime" : ISODate("2014-11-09T02:00:44.496Z")
}

mongodb 是支持組合索引的,那么,_id.nickname 是不是也可以作為索引用呢?

在選中的 collection 上執行 .find({"id.nickname":"busyStone"}).explain()nscanned 字段並不是預想中的 1,因為,建立的索引是這樣的:

{
    "_id" : 1
}

所以,老老實實自己個建索引吧。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM