[教程]MongoDB 從入門到進階 (概要 以及 高級索引篇 TimeToLive GeoNear)


MongoDB概要

[關於MongoDB]

    官方網站: www.mongodb.com

    MongoDB屬於比較典型的NoSql數據庫。和Relationship數據庫相比,其數據屬於文檔結構。

    最新版本的MongoDB為2.2.2   不支持WindowsXP

[C#官方驅動程序]

     GitHub:https://github.com/mongodb/mongo-csharp-driver

[管理工具]

     這里選用本人自制的可視化管理工具作為教程的演示工具。

     大聲呼吁:有興趣的同志,加入這個工具的開發

     下載地址: http://www.wojilu.com/Forum1/Topic/4601

     GitHub:   https://github.com/magicdict/MagicMongoDBTool

[建立第一個空數據庫]

      關於MongoDB的安裝,已經有很多文章介紹了。

      這里推薦CNBLOGS網友 百靈 的Mongodb之(初識如故)

      安裝這篇文章,應該可以正確安裝MongoDB,其實就是下載和解壓,完全綠色軟件。

      這個系列的教程,我將MongoDB解壓到:C:\runmongo,可執行文件則都在C:\runmongo\bin下面。

      新建一個MongoDB實例的方法很多,這里我新建了一個BAT文件,在BAT文件里面寫了3句命令:

      第一句:將執行目錄切換到Mongo可執行目錄

      第二句:新建一個目錄,MongoDB實例需要一個存放文件的目錄,這里我選擇新建一個C:\mongodb\magicdict 目錄

      第三句,則是新建一個MongoDB實例,同時,將MongoDB實例的偵聽端口設置為 28030

     關於MongoDB的啟動參數,推薦 咫尺天涯的文章:mongodb啟動參數

 

1 cd C:\runmongo\bin
2 mkdir C:\mongodb\magicdict
3 mongod --port  28030 --dbpath C:\mongodb\magicdict --rest

 

如果成功的話,將會有一個黑色的DOS控制台出現。當然,這個控制台只是日志輸出,無法操作。你也可以將日志存放到一個文件里面。

 

這個時候去查看  C:\mongodb\magicdict,系統自動添加了一個 mongod.lock  鎖文件。

接下來,啟動可視化工具,看看數據庫吧。

第一次啟動時候,選擇語言:

由於某些功能需要使用mongo的可執行文件,在可執行文件里面選擇可執行文件路徑

 下面是連接管理界面,里面列出了所有現存的連接

 單擊添加按鈕

          由於是最簡單的數據庫,我們只需要填寫 連接名稱,主機,端口號即可。

          連接名稱:這個可以使任意字符,是便於用戶記憶的。

          主機:這里填寫服務器的IP地址,這里使用 localhost 表示本機

           端口:28030

這里你可以先使用 [測試] 按鈕,檢驗一下設置是否正確。如果沒有問題,則可以[添加]連接。

選中剛才建立的連接,按下[確定]按鈕。則進入主界面。

界面左邊的是當前連接(MongoDB實例)中所包含的數據庫對象。當然,這個連接里面只是單純的數據庫。除了有一個系統自動生成的local數據庫以外,什么都沒有。

界面右邊的是當前連接的狀態信息。 關於這些狀態信息,你可以參看官方的幫助文檔: http://docs.mongodb.org/manual/reference/server-status/

 一般來說,我們不會在local系統目錄里面添加數據,一般都會新建一個數據庫來保存用戶數據。

當然,你可以 選中Connection節點,然后用主菜單或者右鍵菜單來 [新建數據庫]。不過,這里將演示如何使用C#來創建數據庫,添加數據。

  1 using System;
  2 using System.Collections.Generic;
  3 using System.Linq;
  4 using System.Text;
  5 using MongoDB.Driver;
  6 using MongoDB.Bson;
  7 using MongoDB.Driver.GridFS;
  8 using MongoDB.Bson.Serialization.Attributes;
  9 
 10 namespace MagicMongoDBTool.Module
 11 {
 12     public static class InitTestData
 13     {
 14         internal class User
 15         {
 16             [BsonId]
 17             public String ID;
 18             [BsonElementAttribute("fn")]
 19             public String Name;
 20             public Byte Age;
 21             public Byte Age2;
 22             public Byte Age3;
 23             public Address address;
 24         }
 25         internal class Address
 26         {
 27             public String street;
 28             public String City;
 29             public String state;
 30             public int Zip;
 31 
 32         }
 33         internal class GeoObject
 34         {
 35             [BsonId]
 36             public String ID;
 37             public int[] Geo;
 38         }
 39         internal class TLLObject
 40         {
 41             [BsonId]
 42             public String ID;
 43             public DateTime CreateDateTime;
 44             public int Game;
 45         }
 46         public static void FillDataForGeoObject(MongoServer mongosvr)
 47         {
 48             MongoDatabase mongodb = mongosvr.GetDatabase("mongodb");
 49             MongoCollection<User> mongoCol = mongodb.GetCollection<User>("GEO");
 50             mongoCol.RemoveAll();
 51             Random Ro = new Random();
 52             ///HugeData
 53             for (int i = 0; i < 1000; i++)
 54             {
 55                 mongoCol.Insert(new GeoObject()
 56                 {
 57                     ID = i.ToString(),
 58                     Geo = new int[2] { Ro.Next() % 180, Ro.Next() % 180 } 
 59                     //[-180,180] 如果已經有索引,則操作這個范圍的記錄無法插入數據庫
 60                 });
 61             }
 62         }
 63         public static void FillDataForTTL(MongoServer mongosvr)
 64         {
 65             MongoDatabase mongodb = mongosvr.GetDatabase("mongodb");
 66             MongoCollection<User> mongoCol = mongodb.GetCollection<User>("TTL");
 67             mongoCol.RemoveAll();
 68             Random Ro = new Random();
 69             ///HugeData
 70             for (int i = 0; i < 1000; i++)
 71             {
 72                 mongoCol.Insert(new TLLObject()
 73                 {
 74                     ID = i.ToString(),
 75                     CreateDateTime = System.DateTime.Now.AddSeconds(i),
 76                     Game = Ro.Next()
 77                 });
 78             }
 79         }
 80         public static void FillDataForUser(MongoServer mongosvr)
 81         {
 82             MongoDatabase mongodb = mongosvr.GetDatabase("mongodb");
 83 
 84             MongoCollection<BsonDocument> mongoJsCol = mongodb.GetCollection<BsonDocument>("system.js");
 85             mongoJsCol.Insert<BsonDocument>(
 86                           new BsonDocument().Add("_id", "sum")
 87                                             .Add("value", "function (x, y) { return x + y; }"));
 88             MongoGridFS mongofs = mongodb.GetGridFS(new MongoGridFSSettings());
 89             MongoCollection<User> mongoCol = mongodb.GetCollection<User>("User");
 90             mongoCol.RemoveAll();
 91             Random Ro = new Random();
 92             ///HugeData
 93             for (int i = 0; i < 1000; i++)
 94             {
 95                 mongoCol.Insert(new User()
 96                 {
 97                     ID = i.ToString(),
 98                     Name = "Tom",
 99                     Age = (byte)Ro.Next(100),
100                     Age2 = (byte)Ro.Next(100),
101                     Age3 = (byte)Ro.Next(100),
102                     address = new Address()
103                     {
104                         street = "123 Main St.",
105                         City = "Centerville",
106                         state = "PA",
107                         Zip = Ro.Next(20)
108                     }
109                 });
110             }
111         }
112     }
113 }

這里我新建了一個mongodb的數據庫,同時新增了3個演示用數據集(collection)。

具體的操作方法,推薦 碼農的文章:  MongoDB的C#驅動程序教程(譯)

這里有非常詳細的C#操作數據庫的解釋。全部是官方文檔的翻譯,可能是機器翻譯的,但是對於英語不好的同志來說,有一定幫助。

當然,如果你的英語還可以,原汁原味的在這里:http://www.mongodb.org/display/DOCS/CSharp+Driver+Tutorial

MongoDB的對象存取,代碼看上去有點ORM的味道,不過,由於MongoDB已經是階層數據庫了,完全不需要將Object進行映射(Map),而是直接存取到數據庫中。

在簡單類的時候,由於數據結構只是二維表格,這種優勢不是很明顯。在復雜類的時候,出現層次結構的時候,則效果非常明顯。

下圖則通過[樹形視圖]來直觀展示了復雜階層的類。

關系型數據庫,需要將User數據和Address數據放在兩張表中,然后用主鍵連接成視圖。

階層型數據庫,則已經將User和Address信息放在一個文檔(Document,類似於記錄的概念)里面。

(當然,關系型的好處也非常明顯,可以減少數據冗余,靈活性也非常好。階層型數據庫在編碼上,可能更加貼近OOP)

 

 [索引-TTL索引]

 索引都是為了檢索的性能而生的,MongoDB的索引也不例外。

 TTL(TimeToLive)索引(MongoDB2.2.2新增)和地理位置索引(“2d”)則是MongoDB的特色。

 TTL索引,索引對象是一個日期型字段,然后需要設定一個有效時間。通過監視 日期型字段的值和當前系統時間,參考有效時間,判斷是否數據過期,對於過期的數據則自動刪除。

 這個特性對於自動刪除日志這樣的操作來說,將非常有用。例如我們可以對於 日志創建時間 進行索引,同時設定過期時間為 3600秒,這樣系統將自動刪除一個小時之前的日志。

 這里我們准備了TTL這樣的一個數據集:

 數據集里面包含了一個CreateDateTime的日期型字段,里面存放着建立記錄的時間。

 接着我們選中數據集,通過索引管理器建立索引。

 我們將對於CreateDateTime建立所以,同時設定有效時間為180秒。

 這樣的話,如果CreateDateTime和系統時間相差180秒,則記錄將會被自動刪除。

1.TTL索引必須建立在日期型字段(或者日期型字段數組)

2.不能建立在復雜索引上

3.你不能在 _id或者任何一個已經存在索引的字段上建立TTL索引

TTL索引的官方說明:  http://docs.mongodb.org/manual/tutorial/expire-data/

注意上面這張圖的左邊,顯示了數據集的索引信息:

AutoDelete的索引過期時間為180秒。而默認的索引_id,則沒有設定過期時間。

同時,里面的數據已經全部被系統自動刪除掉了。

[索引-GEO索引]

如果,你的數據集里面有一個地理位置字段(所謂的地理位置字段,是一個數組,數組里面有兩個數字,數字的范圍是 [-180,180])。

例如,下面的Geo字段,就是一個地理位置字段。

 我們可以對於地理位置字段,進行“2d”索引,或者說是Geo索引。

觀察一下索引類型:這里顯示的是 “2d”,表示這是一個Geo地理索引

建立過地理索引的數據集,可以進行GeoNear查詢。

官方文檔:  http://docs.mongodb.org/manual/applications/geospatial-indexes/

GeoNear的意思就是:查詢一下,指定的坐標附近,有那些記錄。

你可以指定:  1.需要查詢多少個最鄰近的記錄。

                  2.你可以限制最大的距離。

                  3.由於地理坐標的單位是弧度【-180,180】,有時候你需要將距離放大一些,你可以指定距離乘積

                 4.Spherical(球形)

下面我們要查詢離坐標 【100,100】,距離在10以內的記錄,我們限制最多查詢100個記錄。

並且我們不需要系統對於距離進行放大或者縮小的處理。

查詢結果:我們掃描了23個記錄(由於有索引,所以不需要掃描全部記錄),掃描時間為0

              符合條件的記錄有6個,平均距離為 6.34 最大距離為 9.21

              每條記錄的詳細信息都可以在結果里面看到。

 

            


免責聲明!

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



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