Mongo
MongoDB 是一個(gè)基于分布式文件存儲(chǔ)的數(shù)據(jù)庫。由C++語言編寫。旨在為WEB應(yīng)用提供可擴(kuò)展的高性能數(shù)據(jù)存儲(chǔ)解決方案。
MongoDB 是一個(gè)介于關(guān)系數(shù)據(jù)庫和非關(guān)系數(shù)據(jù)庫之間的產(chǎn)品,是非關(guān)系數(shù)據(jù)庫當(dāng)中功能最豐富,最像關(guān)系數(shù)據(jù)庫的。他支持的數(shù)據(jù)結(jié)構(gòu)非常松散,是類似json的bson格式,因此可以存儲(chǔ)比較復(fù)雜的數(shù)據(jù)類型。Mongo最大的特點(diǎn)是他支持的查詢語言非常強(qiáng)大,其語法有點(diǎn)類似于面向?qū)ο蟮牟樵冋Z言,幾乎可以實(shí)現(xiàn)類似關(guān)系數(shù)據(jù)庫單表查詢的絕大部分功能,而且還支持對(duì)數(shù)據(jù)建立索引。、
入門
安裝Mongo
windows安裝
http://www.runoob.com/mongodb/mongodb-window-install.html
linux安裝
https://www.cnblogs.com/pfnie/articles/6759105.html
基本操作
創(chuàng)建數(shù)據(jù)庫
use DATABASE_NAME 創(chuàng)建/切換數(shù)據(jù)庫
查看當(dāng)前所在庫
db 查看當(dāng)前所在庫
查看所有庫
show dbs 查看所有庫
刪除db
db.dropDatabase() 刪除庫(先進(jìn)入庫use dbname)
創(chuàng)建集合(表)
db.createCollection("tableName")
createCollection四個(gè)參數(shù):
capped(布爾型):
如果為 true,則創(chuàng)建固定集合。固定集合是指有著固定大小的集合,當(dāng)達(dá)到最大值時(shí),它會(huì)自動(dòng)覆蓋最早的文檔。當(dāng)該值為 true 時(shí),必須指定 size 參數(shù)。
autoIndexId(布爾型):
如為 true,自動(dòng)在 _id 字段創(chuàng)建索引。默認(rèn)為 false。
size(數(shù)值型):
為固定集合指定一個(gè)最大值(以字節(jié)計(jì))。如果 capped 為 true,也需要指定該字段。
max(數(shù)值型):
指定固定集合中包含文檔的最大數(shù)量。
例子:
db.createCollection(
"tablename1",
{
capped : true,
autoIndexId : true,
size : 6142800,
max : 10000
}
)
刪除集合(表)
db.tableName.drop()
顯示當(dāng)前db狀態(tài)
db.stats();
當(dāng)前db版本
db.version();
查看命令提示
db.help(); db.tableName.help(); db.tableName.find().help();
增刪改查
插入文檔
db.tableName.insert()
例子:
db.user.insert({ "name" : "zhangsan", "age" : 15})
查詢文檔
db.tableName.find()
兩個(gè)參數(shù):
query 條件
例子:
db.tableName.find({"name":"zhangsan"})
projection 返回文檔的信息(返回的列)
例子:
db.tableName.find({"name":"zhangsan"}, {"name":0, "age":1})
注意:值只有0和1,1表示顯示項(xiàng),0表示不顯示項(xiàng)
條件操作符
| sql | 語義 | mongo | 列子 |
|---|---|---|---|
| > | 大于 | $gt | db.tableName.find({"age":{$gt:15}}) |
| < | 小于 | $lt | |
| >= | 大于等于 | $gte | |
| != | 不等于 | $ne | |
| in | 在...里面 | $in | db.tableName.find({"name":{"$in":["zhangsan","lisi"]}}) |
| or | 或者 | $or | db.tableName.find({"gender": "boy", $or: [{"name": "zhangsan"}) |
$type操作符
| 類型 | 代號(hào)值 |
|---|---|
| Double | 1 |
| String | 2 |
| Object | 3 |
| Array | 4 |
| Binary data | 6 |
| Object id | 7 |
| Boolean | 8 |
| Date | 9 |
| Null | 10 |
| JavaScript | 13 |
模糊查詢
正則匹配:
$regex
例子:
db.tableName.find({"name":{$regex:"zhang"}})
刪除文檔
db.tableName.remove(
<query>,
<justOne>
)
uery :(可選)刪除的文檔的條件。
justOne : (可選)如果設(shè)為 true 或 1,則只刪除一個(gè)文檔。
例子:
db.tableName.remove({"name":"zhangsan"})
更新文檔
db.tableName.update(
<query>,
<update>,
{
upsert: <boolean>,
multi: <boolean>,
writeConcern: <document>
}
)
query : update的查詢條件,類似sql update查詢內(nèi)where后面的。
update : update的對(duì)象和一些更新的操作符,也可以理解為sql update查詢內(nèi)set后面的。(https://blog.csdn.net/sunnyyoona/article/details/52420210)
upsert : 可選,這個(gè)參數(shù)的意思是,如果不存在update的記錄,是否插入objNew,true為插入,默認(rèn)是false,不插入。
multi : 可選,mongodb 默認(rèn)是false,只更新找到的第一條記錄,如果這個(gè)參數(shù)為true,就把按條件查出來多條記錄全部更新。
writeConcern : 可選,拋出異常的級(jí)別。
例子:
db.tableName.update({"name":"zhangsan"}, {"name":"wangwu", age:18})
分頁排序
分頁
limit與skip
limit(number) 讀取指定數(shù)量數(shù)據(jù)
例子:
db.tableName.find().limit(2) 顯示兩條數(shù)據(jù)
skip(number) 跳過指定數(shù)量的數(shù)據(jù)
例子:
db.tableName.find().skip(2) 跳過前面兩條數(shù)據(jù),從第三條開始讀取
排序
sort({KEY:1})
例子:
db.tableName.find().sort({"age" : -1}) 1升-1降
注意:skip(), limilt(), sort()三個(gè)放在一起執(zhí)行的時(shí)候,執(zhí)行的順序是先 sort(), 然后是 skip(),最后是limit()。
索引
查看索引
getIndexes() 方法可以用來查看集合的所有索引
totalIndexSize() 查看集合索引的總大小
創(chuàng)建索引
字段索引
db.tableName.ensureIndex({KEY:1}, {options})
例子:
db.tableName.ensureIndex({"name" : 1})
keys,要建立索引的參數(shù)列表。如:{KEY:1},其中key表示字段名,1表示升序排序,也可使用使用數(shù)字-1降序。
options,可選參數(shù),表示建立索引的設(shè)置。可選值如下:
| 參數(shù) | 類型 | 描述 |
|---|---|---|
| background | Boolean | 在后臺(tái)建立索引,以便建立索引時(shí)不阻止其他數(shù)據(jù)庫活動(dòng),默認(rèn)值 false |
| unique | Boolean | 創(chuàng)建唯一索引,默認(rèn)值 false |
| name | String | 指定索引的名稱,如果未指定,MongoDB會(huì)生成一個(gè)索引字段的名稱和排序順序串聯(lián),名字長(zhǎng)度限制為125字節(jié) |
| dropDups | Boolean | 創(chuàng)建唯一索引時(shí),如果出現(xiàn)重復(fù)刪除后續(xù)出現(xiàn)的相同索引,只保留第一個(gè) |
| sparse | Boolean | 對(duì)文檔中不存在的字段數(shù)據(jù)不啟用索引,默認(rèn)值是 false |
| v | index version | 索引的版本號(hào) |
| weights | document | 索引權(quán)重值,數(shù)值在 1 到 99,999 之間,表示該索引相對(duì)于其他索引字段的得分權(quán)重 |
復(fù)合索引
復(fù)合索引也稱多字段索引
db.tableName.ensureIndex({"name":1,"age":-1})
多鍵索引
多鍵索引與單鍵索引創(chuàng)建形式相同,區(qū)別在于字段的值.值具有多個(gè)記錄,例如數(shù)組。
db.tableName.insert({x:[1,2,3,4]})
過期索引
過期索引只能建立在時(shí)間類型上(時(shí)間數(shù)組也行,數(shù)字是以最小時(shí)間為標(biāo)準(zhǔn)),不能使用時(shí)間戳;不能是復(fù)合索引;刪除時(shí)間不是非常精確(刪除也需要時(shí)間)。
db.tableName.ensureIndex({"time":1},{expireAfterSeconds:10})
db.zhoucl.insert({"name":"zhangsan"+50, "age":14, "gender":"難","time":new Date()})
//插入數(shù)據(jù)十秒后將被刪除
全文索引(文本索引)
能解決快速文本查找的需求,每張表只允許創(chuàng)建一個(gè)全文索引;全文索引只能指定一個(gè)$text;
普通全文索引
db.tableName.ensureIndex({"key":"text"})
多列全文索引
db.tableName.ensureIndex({"key":"text", "key2":"text"})
所有列
db.tableName.ensureIndex({"$**":"text"})
查詢指定關(guān)鍵字:{"$search" : "查詢關(guān)鍵字"}
查詢多個(gè)關(guān)鍵字(或關(guān)系):{"$search" : "查詢關(guān)鍵字 查詢關(guān)鍵字 ......"}
查詢多個(gè)關(guān)鍵字(與關(guān)系):{"$search" : ""查詢關(guān)鍵字" "查詢關(guān)鍵字" ......"} # "轉(zhuǎn)義字符
排除多個(gè)關(guān)鍵字(排除某一個(gè)):{"$search" : ""查詢關(guān)鍵字" "查詢關(guān)鍵字"...... - 排除關(guān)鍵字"}
相似度查詢
db.tableName.find({$text:{$search:"aa bb"}}, {score:{$meta:"textSore"}}})
排序
db.tableName.find({$text:{$search:"aa"}}, {score:{$meta:"textScore"}}).sort({score:{$meta:"textScore"}})
其他類型索引
哈希索引(Hashed Index) 是指按照某個(gè)字段的hash值來建立索引,目前主要用于MongoDB Sharded
Cluster的Hash分片,hash索引只能滿足字段完全匹配的查詢,不能滿足范圍查詢等。
地理位置索引(Geospatial Index)能很好的解決O2O的應(yīng)用場(chǎng)景,比如『查找附近的美食』、『查找某個(gè)區(qū)域內(nèi)的車站』等。
聚合
aggregate主要用于處理數(shù)據(jù)(諸如統(tǒng)計(jì)平均值,求和等),并返回計(jì)算后的數(shù)據(jù)結(jié)果。
aggregate()是基于數(shù)據(jù)處理的聚合管道,每個(gè)文檔通過一個(gè)由多個(gè)階段(stage)組成的管道,可以對(duì)每個(gè)階段的管道進(jìn)行分組、過濾等功能,然后經(jīng)過一系列的處理,輸出相應(yīng)的結(jié)果。Mongo還提供了一些聚合函數(shù)如:count(),distinct()。
語法:
db.collection.aggregate(pipeline, options)
gourp聚合:
group做的聚合有些復(fù)雜。先選定分組所依據(jù)的鍵,此后MongoDB就會(huì)將集合依據(jù)選定鍵值的不同分成若干組。然后可以通過聚合每一組內(nèi)的文檔,產(chǎn)生一個(gè)結(jié)果文檔。
$group聚合相關(guān)表達(dá)式:
| 表達(dá)式 | 描述 | 實(shí)例 |
|---|---|---|
| $sum | 計(jì)算總和 | db.mycol.aggregate([{ |
| $avg | 計(jì)算平均值 | db.tableName.aggregate([{ |
| $min | 獲取集合中所有文檔對(duì)應(yīng)值得最小值 | db.tableName.aggregate([{ |
| $max | 獲取集合中所有文檔對(duì)應(yīng)值得最大值 | db.tableName.aggregate([{ |
| $push | 在結(jié)果文檔中插入值到一個(gè)數(shù)組中 | db.tableName.aggregate([{ |
| $addToSet | 在結(jié)果文檔中插入值到一個(gè)數(shù)組中,但不創(chuàng)建副本 | db.tableName.aggregate([{ |
| $first | 根據(jù)資源文檔的排序獲取第一個(gè)文檔數(shù)據(jù) | db.tableName.aggregate([{ |
| $last | 根據(jù)資源文檔的排序獲取最后一個(gè)文檔數(shù)據(jù) | db.tableName.aggregate([{ |
例子1:
數(shù)據(jù)如下:
{_id: 1, title: 'MongoDB Overview', description: 'MongoDB is no sql database', by_user: 'runoob.com', url: 'http://www.runoob.com',tags: ['mongodb', 'database', 'NoSQL'],likes: 100},
{_id: 2, title: 'NoSQL Overview', description: 'No sql database is very fast', by_user: 'runoob.com', url: 'http://www.runoob.com', tags: ['mongodb', 'database', 'NoSQL'], likes: 10},
{_id: 3, title: 'Neo4j Overview', description: 'Neo4j is no sql database', by_user: 'Neo4j', url: 'http://www.neo4j.com', tags: ['neo4j', 'database', 'NoSQL'], likes: 750 }
聚合函數(shù)如下:
db.tableName.aggregate(
[
{
$group : {
_id : "$by_user",
num_tutorial : {
$sum : 1
}
}
}
]
)
結(jié)果如下:
{ "_id" : "runoob.com", "num_tutorial" : 2}
{ "_id" : "Neo4j", "num_tutorial" : 1}
例子2:
數(shù)據(jù)如下:
{ "_id" : 1, "item" : "abc", "price" : 10, "quantity" : 2, "date" : ISODate("2014-03-01T08:00:00Z") }
{ "_id" : 2, "item" : "jkl", "price" : 20, "quantity" : 1, "date" : ISODate("2014-03-01T09:00:00Z") }
{ "_id" : 3, "item" : "xyz", "price" : 5, "quantity" : 10, "date" : ISODate("2014-03-15T09:00:00Z") }
{ "_id" : 4, "item" : "xyz", "price" : 5, "quantity" : 20, "date" : ISODate("2014-04-04T11:21:39.736Z") }
{ "_id" : 5, "item" : "abc", "price" : 10, "quantity" : 10, "date" : ISODate("2014-04-04T21:23:13.331Z") }
聚合函數(shù)如下:
db.tableName.aggregate([
{
$group : {
_id : { month: { $month: "$date" }, day: { $dayOfMonth: "$date" }, year: { $year: "$date" } },
totalPrice: { $sum: { $multiply: [ "$price", "$quantity" ] } },
averageQuantity: { $avg: "$quantity" },
count: { $sum: 1 }
}
}
]
)
結(jié)果如下:
{ "_id" : { "month" : 3, "day" : 15, "year" : 2014 }, "totalPrice" : 50, "averageQuantity" : 10, "count" : 1 }
{ "_id" : { "month" : 4, "day" : 4, "year" : 2014 }, "totalPrice" : 200, "averageQuantity" : 15, "count" : 2 }
{ "_id" : { "month" : 3, "day" : 1, "year" : 2014 }, "totalPrice" : 40, "averageQuantity" : 1.5, "count" : 2 }
其他聚合:
count
db.tableName.find().count() 統(tǒng)計(jì)總數(shù)
distinct
db.collection_name.distinct(field,query,options) 去重復(fù)
管道
MongoDB的聚合管道將MongoDB文檔在一個(gè)管道處理完畢后將結(jié)果傳遞給下一個(gè)管道處理。管道操作是可以重復(fù)的。
管道表達(dá)式:
| 表達(dá)式 | 描述 |
|---|---|
| $project | 修改輸入文檔的結(jié)構(gòu)??梢杂脕碇孛?、增加或刪除域,也可以用于創(chuàng)建計(jì)算結(jié)果以及嵌套文檔 |
| $match | 用于過濾數(shù)據(jù),只輸出符合條件的文檔。$match使用MongoDB的標(biāo)準(zhǔn)查詢操作 |
| $limit | 用來限制MongoDB聚合管道返回的文檔數(shù) |
| $skip | 在聚合管道中跳過指定數(shù)量的文檔,并返回余下的文檔 |
| $unwind | 將文檔中的某一個(gè)數(shù)組類型字段拆分成多條,每條包含數(shù)組中的一個(gè)值 |
| $group | 將集合中的文檔分組,可用于統(tǒng)計(jì)結(jié)果 |
| $sort | 將輸入文檔排序后輸出 |
| $geoNear | 輸出接近某一地理位置的有序文檔 |
例子:
db.test.aggregate(
[
{
$group : {
_id : "$by_user",
num_tutorial : {
$sum : 1
}
}
},
{ $skip : 1 }
]
)