摘要:將返回結果限制為前個。所以,聚合的結果必須要限制在以內支持的最大響應消息大小。包含字段和排除字段的規則與常規查詢中的語法一致。改變字符大小寫的操作,只保證對羅馬字符有效。只對羅馬字符組成的字符串有效。
上一篇文章:MongoDB指南---15、特殊的索引和集合:地理空間索引、使用GridFS存儲文件
下一篇文章:MongoDB指南---17、MapReduce
如果你有數據存儲在MongoDB中,你想做的可能就不僅僅是將數據提取出來那么簡單了;你可能希望對數據進行分析并加以利用。本章介紹MongoDB提供的聚合工具:
聚合框架;
MapReduce;
幾個簡單聚合命令:count、distinct和group。
聚合框架使用聚合框架可以對集合中的文檔進行變換和組合。基本上,可以用多個構件創建一個管道(pipeline),用于對一連串的文檔進行處理。這些構件包括篩選(filtering)、投射(projecting)、分組(grouping)、排序(sorting)、限制(limiting)和跳過(skipping)。
例如,有一個保存著雜志文章的集合,你可能希望找出發表文章最多的那個作者。假設每篇文章被保存為MongoDB中的一個文檔,可以按照如下步驟創建管道。
將每個文章文檔中的作者投射出來。
將作者按照名字排序,統計每個名字出現的次數。
將作者按照名字出現次數降序排列。
將返回結果限制為前5個。
這里面的每一步都對應聚合框架中的一個操作符:
{"$project" : {"author" : 1}}
這樣可以將"author"從每個文檔中投射出來。
這個語法與查詢中的字段選擇器比較像:可以通過指定"fieldname" : 1選擇需要投射的字段,或者通過指定"fieldname":0排除不需要的字段。執行完這個"$project"操作之后,結果集中的每個文檔都會以{"_id" : id, "author" : "authorName"}這樣的形式表示。這些結果只會在內存中存在,不會被寫入磁盤。
{"$group" : {"_id" : "$author", "count" : {"$sum" : 1}}}
這樣就會將作者按照名字排序,某個作者的名字每出現一次,就會對這個作者的"count"加1。
這里首先指定了需要進行分組的字段"author"。這是由"_id" : "$author"指定的。可以將這個操作想象為:這個操作執行完后,每個作者只對應一個結果文檔,所以"author"就成了文檔的唯一標識符("_id")。
第二個字段的意思是為分組內每個文檔的"count"字段加1。注意,新加入的文檔中并不會有"count"字段;這"$group"創建的一個新字段。
執行完這一步之后,結果集中的每個文檔會是這樣的結構:
{"_id" : "authorName", "count" : articleCount}。
{"$sort" : {"count" : -1}}
這個操作會對結果集中的文檔根據"count"字段進行降序排列。
{"$limit" : 5}
這個操作將最終的返回結果限制為當前結果中的前5個文檔。
在MongoDB中實際運行時,要將這些操作分別傳給aggregate()函數:
> db.articles.aggregate({"$project" : {"author" : 1}}, ... {"$group" : {"_id" : "$author", "count" : {"$sum" : 1}}}, ... {"$sort" : {"count" : -1}}, ... {"$limit" : 5}) { "result" : [ { "_id" : "R. L. Stine", "count" : 430 }, { "_id" : "Edgar Wallace", "count" : 175 }, { "_id" : "Nora Roberts", "count" : 145 }, { "_id" : "Erle Stanley Gardner", "count" : 140 }, { "_id" : "Agatha Christie", "count" : 85 } ], "ok" : 1 }
aggregate()會返回一個文檔數組,其中的內容是發表文章最多的5個作者。
如果管道沒有給出預期的結果,就需要進行調試,調試時,可以先只指定第一個管道操作符。如果這時得到了預期結果,那就再指定第二個管道操作符。以前面的例子來說,首先要試著只使用"$project"操作符進行聚合;如果這個操作符的結果是有效的,就再添加"$group"操作符;如果結果還是有效的,就再添加"$sort";最后再添加"$limit"操作符。這樣就可以逐步定位到造成問題的操作符。
本書寫作時,聚合框架還不能對集合進行寫入操作,因此所有結果必須返回給客戶端。所以,聚合的結果必須要限制在16 MB以內(MongoDB支持的最大響應消息大小)。
管道操作符每個操作符都會接受一連串的文檔,對這些文檔做一些類型轉換,最后將轉換后的文檔作為結果傳遞給下一個操作符(對于最后一個管道操作符,是將結果返回給客戶端)。
不同的管道操作符可以按任意順序組合在一起使用,而且可以被重復任意多次。例如,可以先做"$match",然后做"$group",然后再做"$match"(與之前的"$match"匹配不同的查詢條件)。
$match用于對文檔集合進行篩選,之后就可以在篩選得到的文檔子集上做聚合。例如,如果想對Oregon(俄勒岡州,簡寫為OR)的用戶做統計,就可以使用{$match : {"state" : "OR"}}。"$match"可以使用所有常規的查詢操作符("$gt"、"$lt"、"$in"等)。有一個例外需要注意:不能在"$match"中使用地理空間操作符。
通常,在實際使用中應該盡可能將"$match"放在管道的前面位置。這樣做有兩個好處:一是可以快速將不需要的文檔過濾掉,以減少管道的工作量;二是如果在投射和分組之前執行"$match",查詢可以使用索引。
相對于“普通”的查詢而言,管道中的投射操作更加強大。使用"$project"可以從子文檔中提取字段,可以重命名字段,還可以在這些字段上進行一些有意思的操作。
最簡單的一個"$project"操作是從文檔中選擇想要的字段。可以指定包含或者不包含一個字段,它的語法與查詢中的第二個參數類似。如果在原來的集合上執行下面的代碼,返回的結果文檔中只包含一個"author"字段。
> db.articles.aggregate({"$project" : {"author" : 1, "_id" : 0}})
默認情況下,如果文檔中存在"_id"字段,這個字段就會被返回("_id"字段可以被一些管道操作符移除,也可能已經被之前的投射操作給移除了)。可以使用上面的代碼將"_id"從結果文檔中移除。包含字段和排除字段的規則與常規查詢中的語法一致。
也可以將投射過的字段進行重命名。例如,可以將每個用戶文檔的"_id"在返回結果中重命名為"userId":
> db.users.aggregate({"$project" : {"userId" : "$_id", "_id" : 0}}) { "result" : [ { "userId" : ObjectId("50e4b32427b160e099ddbee7") }, { "userId" : ObjectId("50e4b32527b160e099ddbee8") } ... ], "ok" : 1 }
這里的"$fieldname"語法是為了在聚合框架中引用fieldname字段(上面的例子中是"_id")的值。例如,"$age"會被替換為"age"字段的內容(可能是數值,也可能是字符串),"$tags.3"會被替換為tags數組中的第4個元素。所以,上面例子中的"$_id"會被替換為進入管道的每個文檔的"_id"字段的值。
注意,必須明確指定將"_id"排除,否則這個字段的值會被返回兩次:一次被標為"userId",一次被標為"_id"。可以使用這種技術生成字段的多個副本,以便在之后的"$group"中使用。
在對字段進行重命名時,MongoDB并不會記錄字段的歷史名稱。因此,如果在"originalFieldname"字段上有一個索引,聚合框架無法在下面的排序操作中使用這個索引,盡管人眼一下子就能看出下面代碼中的"newFieldname"與"originalFieldname"表示同一個字段。
> db.articles.aggregate({"$project" : {"newFieldname" : "$originalFieldname"}}, ... {"$sort" : {"newFieldname" : 1}})
所以,應該盡量在修改字段名稱之前使用索引。
1. 管道表達式最簡單的"$project"表達式是包含和排除字段,以及字段名稱("$fieldname")。但是,還有一些更強大的選項。也可以使用表達式(expression)將多個字面量和變量組合在一個值中使用。
在聚合框架中有幾個表達式可用來組合或者進行任意深度的嵌套,以便創建復雜的表達式。
算術表達式可用于操作數值。指定一組數值,就可以使用這個表達式進行操作了。例如,下面的表達式會將"salary"和"bonus"字段的值相加。
> db.employees.aggregate( ... { ... "$project" : { ... "totalPay" : { ... "$add" : ["$salary", "$bonus"] ... } ... } ... })
可以將多個表達式嵌套在一起組成更復雜的表達式。假設我們想要從總金額中扣除為401(k)繳納的金額。可以使用"$subtract"表達式:
401(k)是美國的一種養老金計劃。——譯者注
> db.employees.aggregate( ... { ... "$project" : { ... "totalPay" : { ... "$subtract" : [{"$add" : ["$salary", "$bonus"]}, "$401k"] ... } ... } ... })
表達式可以進行任意層次的嵌套。
下面是每個操作符的語法:
"$add" : [expr1[, expr2, ..., exprN]]
這個操作符接受一個或多個表達式作為參數,將這些表達式相加。
"$subtract" : [expr1, expr2]
接受兩個表達式作為參數,用第一個表達式減去第二個表達式作為結果。
"$multiply" : [expr1[, expr2, ..., exprN]]
接受一個或者多個表達式,并且將它們相乘。
"$divide" : [expr1, expr2]
接受兩個表達式,用第一個表達式除以第二個表達式的商作為結果。
"$mod" : [expr1, expr2]
接受兩個表達式,將第一個表達式除以第二個表達式得到的余數作為結果。
3. 日期表達式(date expression)許多聚合都是基于時間的:上周發生了什么?上個月發生了什么?過去一年間發生了什么?因此,聚合框架中包含了一些用于提取日期信息的表達式:"$year"、“$month”、"$week"、"$dayOfMonth"、"$dayOfWeek"、"$dayOfYear"、"$hour"、"$minute"和"$second"。只能對日期類型的字段進行日期操作,不能對數值類型字段做日期操作。
每種日期類型的操作都是類似的:接受一個日期表達式,返回一個數值。下面的代碼會返回每個雇員入職的月份:
> db.employees.aggregate( ... { ... "$project" : { ... "hiredIn" : {"$month" : "$hireDate"} ... } ... })
也可以使用字面量日期。下面的代碼會計算出每個雇員在公司內的工作時間:
> db.employees.aggregate( ... { ... "$project" : { ... "tenure" : { ... "$subtract" : [{"$year" : new Date()}, {"$year" : "$hireDate"}] ... } ... } ... })4. 字符串表達式(string expression)
也有一些基本的字符串操作可以使用,它們的簽名如下所示:
"$substr" : [expr, startOffset, numToReturn]
其中第一個參數expr必須是個字符串,這個操作會截取這個字符串的子串(從第startOffset字節開始的numToReturn字節,注意,是字節,不是字符。在多字節編碼中尤其要注意這一點)expr必須是字符串。
"$concat" : [expr1[, expr2, ..., exprN]]
將給定的表達式(或者字符串)連接在一起作為返回結果。
"$toLower" : expr
參數expr必須是個字符串值,這個操作返回expr的小寫形式。
"$toUpper" : expr
參數expr必須是個字符串值,這個操作返回expr的大寫形式。
改變字符大小寫的操作,只保證對羅馬字符有效。
下面是一個生成 j.doe@example.com格式的email地址的例子。它提取"$firstname"的第一個字符,將其與多個常量字符串和"$lastname"連接成一個字符串:
> db.employees.aggregate( ... { ... "$project" : { ... "email" : { ... "$concat" : [ ... {"$substr" : ["$firstName", 0, 1]}, ... ".", ... "$lastName", ... "@example.com" ... ] ... } ... } ... })5. 邏輯表達式(logical expression)
有一些邏輯表達式可以用于控制語句。
下面是幾個比較表達式。
"$cmp" : [expr1, expr2]
比較expr1和expr2。如果expr1等于expr2,返回0;如果expr1 < expr2,返回一個負數;如果expr1 >expr2,返回一個正數。
"$strcasecmp" : [string1, string2]
比較string1和string2,區分大小寫。只對羅馬字符組成的字符串有效。
"$eq"/"$ne"/"$gt"/"$gte"/"$lt"/"$lte" : [expr1, expr2]
對expr1和expr2執行相應的比較操作,返回比較的結果(true或false)。
下面是幾個布爾表達式。
"$and" : [expr1[, expr2, ..., exprN]]
如果所有表達式的值都是true,那就返回true,否則返回false。
"$or" : [expr1[, expr2, ..., exprN]]
只要有任意表達式的值為true,就返回true,否則返回false。
"$not" : expr
對expr取反。
還有兩個控制語句。
"$cond" : [booleanExpr, trueExpr, falseExpr]
如果booleanExpr的值是true,那就返回trueExpr,否則返回falseExpr。
"$ifNull" : [expr, replacementExpr]
如果expr是null,返回replacementExpr,否則返回expr。
通過這些操作符,就可以在聚合中使用更復雜的邏輯,可以對不同數據執行不同的代碼,得到不同的結果。
管道對于輸入數據的形式有特定要求,所以這些操作符在傳入數據時要特別注意。算術操作符必須接受數值,日期操作符必須接受日期,字符串操作符必須接受字符串,如果有字符缺失,這些操作符就會報錯。如果你的數據集不一致,可以通過這個條件來檢測缺失的值,并且進行填充。
假如有個教授想通過某種比較復雜的計算為學生打分:出勤率占10%,日常測驗成績占30%,期末考試占60%(如果是老師最寵愛的學生,那么分數就是100)。可以使用如下代碼:
> db.students.aggregate( ... { ... "$project" : { ... "grade" : { ... "$cond" : [ ... "$teachersPet", ... 100, // if ... { // else ... "$add" : [ ... {"$multiply" : [.1, "$attendanceAvg"]}, ... {"$multiply" : [.3, "$quizzAvg"]}, ... {"$multiply" : [.6, "$testAvg"]} ... ] ... } ... ] ... } ... } ... })$group
$group操作可以將文檔依據特定字段的不同值進行分組。下面是幾個分組的例子。
如果我們以分鐘作為計量單位,希望找出每天的平均濕度,就可以根據"day"字段進行分組。
如果有一個學生集合,希望按照分數等級將學生分為多個組,可以根據"grade"字段進行分組。
如果有一個用戶集合,希望知道每個城市有多少用戶,可以根據"state"和"city"兩個字段對集合進行分組,每個"city"/"state"對對應一個分組。不應該只根據"city"字段進行分組,因為不同的州可能擁有相同名字的城市。
如果選定了需要進行分組的字段,就可以將選定的字段傳遞給"$group"函數的"_id"字段。對于上面的例子,相應的代碼如下:
{"$group" : {"_id" : "$day"}} {"$group" : {"_id" : "$grade"}} {"$group" : {"_id" : {"state" : "$state", "city" : "$city"}}}
如果執行這些代碼,結果集中每個分組對應一個只有一個字段(分組鍵)的文檔。例如,按學生分數等級進行分組的結果可能是:{"result" : [{"_id" : "A+"}, {"_id" : "A"}, {"_id" : "A-"}, ..., {"_id" : "F"}], "ok" : 1}。通過上面這些代碼,可以得到特定字段中每一個不同的值,但是所有例子都要求基于這些分組進行一些計算。因此,可以添加一些字段,使用分組操作符對每個分組中的文檔做一些計算。
1. 分組操作符這些分組操作符允許對每個分組進行計算,得到相應的結果。7.1節介紹過"$sum"分組操作符的作用:分組中每出現一個文檔,它就對計算結果加1,這樣便可以得到每個分組中的文檔數量。
2. 算術操作符有兩個操作符可以用于對數值類型字段的值進行計算:"$sum"和"$average"。
"$sum" : value
對于分組中的每一個文檔,將value與計算結果相加。注意,上面的例子中使用了一個字面量數字1,但是這里也可以使用比較復雜的值。例如,如果有一個集合,其中的內容是各個國家的銷售數據,使用下面的代碼就可以得到每個國家的總收入:
> db.sales.aggregate( ... { ... "$group" : { ... "_id" : "$country", ... "totalRevenue" : {"$sum" : "$revenue"} ... } ... })
"$avg" : value
返回每個分組的平均值。
例如,下面的代碼會返回每個國家的平均收入,以及每個國家的銷量:
> db.sales.aggregate( ... { ... "$group" : { ... "_id" : "$country", ... "totalRevenue" : {"$avg" : "$revenue"}, ... "numSales" : {"$sum" : 1} ... } ... })3. 極值操作符(extreme operator)
下面的四個操作符可用于得到數據集合中的“邊緣”值。
"$max" : expr 返回分組內的最大值。
"$min" : expr
返回分組內的最小值。
"$first" : expr 返回分組的第一個值,忽略后面所有值。只有排序之后,明確知道數據順序時這個操作才有意義。
"$last" : expr
與"$first"相反,返回分組的最后一個值。
"$max"和"$min"會查看每一個文檔,以便得到極值。因此,如果數據是無序的,這兩個操作符也可以有效工作;如果數據是有序的,這兩個操作符就會有些浪費。假設有一個存有學生考試成績的數據集,需要找到其中的最高分與最低分:
> db.scores.aggregate( ... { ... "$group" : { ... "_id" : "$grade", ... "lowestScore" : {"$min" : "$score"}, ... "highestScore" : {"$max" : "$score"} ... } ... })
另一方面,如果數據集是按照希望的字段排序過的,那么"$first"和"$last"操作符就會非常有用。下面的代碼與上面的代碼可以得到同樣的結果:
> db.scores.aggregate( ... { ... "$sort" : {"score" : 1} ... }, ... { ... "$group" : { ... "_id" : "$grade", ... "lowestScore" : {"$first" : "$score"}, ... "highestScore" : {"$last" : "$score"} ... } ... })
如果數據是排過序的,那么$first和$last會比$min和$max效率更高。如果不準備對數據進行排序,那么直接使用$min和$max會比先排序再使用$first和$last效率更高。
4. 數組操作符有兩個操作符可以進行數組操作。
"$addToSet" : expr
如果當前數組中不包含expr ,那就將它添加到數組中。在返回結果集中,每個元素最多只出現一次,而且元素的順序是不確定的。
"$push" : expr
不管expr是什么值,都將它添加到數組中。返回包含所有值的數組。
5. 分組行為有兩個操作符不能用前面介紹的流式工作方式對文檔進行處理,"$group"是其中之一。大部分操作符的工作方式都是流式的,只要有新文檔進入,就可以對新文檔進行處理,但是"$group"必須要等收到所有的文檔之后,才能對文檔進行分組,然后才能將各個分組發送給管道中的下一個操作符。這意味著,在分片的情況下,"$group"會先在每個分片上執行,然后各個分片上的分組結果會被發送到mongos再進行最后的統一分組,剩余的管道工作也都是在mongos(而不是在分片)上運行的。
$unwind拆分(unwind)可以將數組中的每一個值拆分為多帶帶的文檔。例如,如果有一篇擁有多條評論的博客文章,可以使用$unwind將每條評論拆分為一個獨立的文檔:
> db.blog.findOne() { "_id" : ObjectId("50eeffc4c82a5271290530be"), "author" : "k", "post" : "Hello, world!", "comments" : [ { "author" : "mark", "date" : ISODate("2013-01-10T17:52:04.148Z"), "text" : "Nice post" }, { "author" : "bill", "date" : ISODate("2013-01-10T17:52:04.148Z"), "text" : "I agree" } ] } > db.blog.aggregate({"$unwind" : "$comments"}) { "results" : { "_id" : ObjectId("50eeffc4c82a5271290530be"), "author" : "k", "post" : "Hello, world!", "comments" : { "author" : "mark", "date" : ISODate("2013-01-10T17:52:04.148Z"), "text" : "Nice post" } }, { "_id" : ObjectId("50eeffc4c82a5271290530be"), "author" : "k", "post" : "Hello, world!", "comments" : { "author" : "bill", "date" : ISODate("2013-01-10T17:52:04.148Z"), "text" : "I agree" } } ], "ok" : 1 }
如果希望在查詢中得到特定的子文檔,這個操作符就會非常有用:先使用"$unwind"得到所有子文檔,再使用"$match"得到想要的文檔。例如,如果要得到特定用戶的所有評論(只需要得到評論,不需要返回評論所屬的文章),使用普通的查詢是不可能做到的。但是,通過提取、拆分、匹配,就很容易了:
> db.blog.aggregate({"$project" : {"comments" : "$comments"}}, ... {"$unwind" : "$comments"}, ... {"$match" : {"comments.author" : "Mark"}})
由于最后得到的結果仍然是一個"comments"子文檔,所以你可能希望再做一次投射,以便讓輸出結果更優雅。
$sort可以根據任何字段(或者多個字段)進行排序,與在普通查詢中的語法相同。如果要對大量的文檔進行排序,強烈建議在管道的第一階段進行排序,這時的排序操作可以使用索引。否則,排序過程就會比較慢,而且會占用大量內存。
可以在排序中使用文檔中實際存在的字段,也可以使用在投射時重命名的字段:
> db.employees.aggregate( ... { ... "$project" : { ... "compensation" : { ... "$add" : ["$salary", "$bonus"] ... }, ... "name" : 1 ... } ... }, ... { ... "$sort" : {"compensation" : -1, "name" : 1} ... })
這個例子會對員工排序,最終的結果是按照報酬從高到低,姓名從A到Z的順序排列。
排序方向可以是1(升序)和-1(降序)。
與前面講過的"$group"一樣,"$sort"也是一個無法使用流式工作方式的操作符。"$sort"也必須要接收到所有文檔之后才能進行排序。在分片環境下,先在各個分片上進行排序,然后將各個分片的排序結果發送到mongos做進一步處理。
$limit會接受一個數字n,返回結果集中的前n個文檔。
$skip$skip也是接受一個數字n,丟棄結果集中的前n個文檔,將剩余文檔作為結果返回。在“普通”查詢中,如果需要跳過大量的數據,那么這個操作符的效率會很低。在聚合中也是如此,因為它必須要先匹配到所有需要跳過的文檔,然后再將這些文檔丟棄。
使用管道應該盡量在管道的開始階段(執行"$project"、"$group"或者"$unwind"操作之前)就將盡可能多的文檔和字段過濾掉。管道如果不是直接從原先的集合中使用數據,那就無法在篩選和排序中使用索引。如果可能,聚合管道會嘗試對操作進行排序,以便能夠有效使用索引。
MongoDB不允許單一的聚合操作占用過多的系統內存:如果MongoDB發現某個聚合操作占用了20%以上的內存,這個操作就會直接輸出錯誤。允許將輸出結果利用管道放入一個集合中是為了方便以后使用(這樣可以將所需的內存減至最小)。
如果能夠通過"$match"操作迅速減小結果集的大小,就可以使用管道進行實時聚合。由于管道會不斷包含更多的文檔,會越來越復雜,所以幾乎不可能實時得到管道的操作結果。
上一篇文章:MongoDB指南---15、特殊的索引和集合:地理空間索引、使用GridFS存儲文件
下一篇文章:MongoDB指南---17、MapReduce
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/19575.html
摘要:將返回結果限制為前個。所以,聚合的結果必須要限制在以內支持的最大響應消息大小。包含字段和排除字段的規則與常規查詢中的語法一致。改變字符大小寫的操作,只保證對羅馬字符有效。只對羅馬字符組成的字符串有效。 上一篇文章:MongoDB指南---15、特殊的索引和集合:地理空間索引、使用GridFS存儲文件下一篇文章:MongoDB指南---17、MapReduce 如果你有數據存儲在Mon...
摘要:操作花費的時間,單位是毫秒。處理完成后,會自動將臨時集合的名字更改為你指定的集合名,這個重命名的過程是原子性的。作用域在這些函數內部是不變的。上一篇文章指南聚合下一篇文章指南聚合命令 上一篇文章:MongoDB指南---16、聚合下一篇文章:MongoDB指南---18、聚合命令 MapReduce是聚合工具中的明星,它非常強大、非常靈活。有些問題過于復雜,無法使用聚合框架的查詢語言...
摘要:操作花費的時間,單位是毫秒。處理完成后,會自動將臨時集合的名字更改為你指定的集合名,這個重命名的過程是原子性的。作用域在這些函數內部是不變的。上一篇文章指南聚合下一篇文章指南聚合命令 上一篇文章:MongoDB指南---16、聚合下一篇文章:MongoDB指南---18、聚合命令 MapReduce是聚合工具中的明星,它非常強大、非常靈活。有些問題過于復雜,無法使用聚合框架的查詢語言...
摘要:不采用關系模型主要是為了獲得更好的擴展性。易于擴展應用程序數據集的大小正在以不可思議的速度增長。過去非常罕見的級別數據,現在已是司空見慣了。這種精簡方式的設計是能夠實現如此高性能的原因之一。下一篇文章指南基礎知識文檔集合數據庫客戶端 下一篇文章:MongoDB指南---2、MongoDB基礎知識-文檔、集合、數據庫、客戶端 MongoDB是一款強大、靈活,且易于擴展的通用型數據庫。它...
摘要:不采用關系模型主要是為了獲得更好的擴展性。易于擴展應用程序數據集的大小正在以不可思議的速度增長。過去非常罕見的級別數據,現在已是司空見慣了。這種精簡方式的設計是能夠實現如此高性能的原因之一。下一篇文章指南基礎知識文檔集合數據庫客戶端 下一篇文章:MongoDB指南---2、MongoDB基礎知識-文檔、集合、數據庫、客戶端 MongoDB是一款強大、靈活,且易于擴展的通用型數據庫。它...
閱讀 1876·2021-09-24 09:48
閱讀 3220·2021-08-26 14:14
閱讀 1674·2021-08-20 09:36
閱讀 1462·2019-08-30 15:55
閱讀 3628·2019-08-26 17:15
閱讀 1426·2019-08-26 12:09
閱讀 607·2019-08-26 11:59
閱讀 3324·2019-08-26 11:57