Mongodb使用, 快速上车

你将会了解到如下:

  1. 了解 MongoDB 体系结构
  2. mongodb 的DRDL语言常用使用方法
  3. mongodb的查询操作实战
  4. Mongodb 的索引使用
  5. Mongodb 的聚合框架
  6. Mongodb3.4的新增功能使用

MongoDB 体系结构

MongoDB 中的物理结构是由一系列物理文件(数据文件、索引文件、日志文件等)的集合与之对应的逻辑结构(集合、文档等)被称之为数据库,简单的说,就是数据库是由一系列与磁盘有关系的物理文件的组成。
MongoDB 的逻辑结构是一种层次结构,主要由:文档(Document)、集合(Collection)、数据库 (database)这三部分组成,逻辑结构是面向用户的,用户使用 MongoDB 开发应用程序使用的就是逻辑结构。
MongoDB 的文档(Document),相当于关系数据库中的一行记录。
多个文档组成一个集合(Collection),相当于关系数据库的表。
多个集合(Collection),扩及上组织在一起,就是数据库(database)。
一个 MongoDB 实例支持多个数据库(database)。
一个 MongoDB 实例包括多个数据库(database)。文档(Document)、集合(Collection)、数据库(Database)的层次结构
MongoDB 与关系型数据库的逻辑结构进行了对比如下:
逻辑 结构对比
Mongodb 关系型数据库
文档(document) 行(row)
字段(column) 字段(column)
集合(collection) 表(table)
数据库(Database) 数据库(Database)
MongoDB 同样具有关系型的事务特性:

  1. 原子性
  2. 隔离性
  3. 一致性
  4. 持久性

mongodb 的 DRDL 语言常用使用方法

mongodb 的 DRDL 语言,DRDL 全称是 Document Relational Definition Language,文档关系定义语言 mongodb 的 DRDL 语言在集合上最常用使用方法有如下:

创建表

db.ux168doc.insertOne( {
id: NumberLong(1),
sku_id: "abc123", modifiedOn: new Date(),
status: "A"
} )

增加字段

db.ux168doc.updateMany(
{ },
{ $set: { outSureDate: new Date() } }
)

删除字段

db.ux168doc.updateMany(
{ },
{ $unset: { "outSureDate": "" } }
)

修改字段

db.ux168doc.update( {}, {$rename:{"location":"last"}},	false, true);

更新

Update stock_movemaster set status=’C’ where age>25 db.stock_movemaster.updateMany({ age: { $gt: 25 } },{ $set: { status: "C" } }) Update stock_movemaster set age=age+3 where status=’A’ db.stock_movemaster.updateMany({ status: "A" } ,{ $inc: { age: 3 } })
db.stock_movemaster.updateMany
({'records.sender':'2'},{'records.$.isRead':true},false,true);
var cursor=db.getCollection('receive_qc_log').find({}) while (cursor.hasNext()){ nc=cursor.next(); v_cid=nc._id;
v_qcId=nc.qcId; v_qcName=nc.qcItemNameCn;
v_qcNameEn=nc.qcItemName;
db.receive_qc_log.update({_id:v_cid},{$set:{'oldQcId':v_qcId,'oldQcName':v_qcName,'ol dQcNameEn':v_qcNameEn}},true)
}

删除

db.people.deleteMany( { status: "D" } ) db.people.deleteMany({})

mongodb 的查询操作实战

  • 查找全部字段的数据
    db.stock_movedetail.find({})
  • 筛选某一个字段显示结果查询,筛选某一个字段显示结果查询,如,只显示字段 Move_ID db.stock_movedetail.find({},{“Move_ID”:1})
  • 筛选某一个字段不显示结果查询
    筛选某一个字段不显示结果查询,如:不显示字段_id
    db.stock_movedetail.find({},{"_id":0})

AND 查询

db.stock_movemaster.find({"Move_OutDate":{$gte:ISODate("2006-0613T16:00:00.000+0000"), $lt:ISODate("2006-06-14T16:00:00.000+0000")}})
db.stock_movemaster.find({$and:[{"Move_OutDate":{$gte:ISODate("2006-06-
13T16:00:00.000+0000")}},{"Move_OutDate":{$lt:ISODate("2006-0614T16:00:00.000+0000")}}]})

排序查询

db.stock_movedetail.find({},{"_id":0}).sort({"Move_ID":1}) db.stock_movedetail.find({},{"_id":0}).sort({"Move_ID":-1})
- 查找前几行数据查询
db.stock_movedetail.find({}).limit(5)
//分页查询
db.stock_movedetail.find({}).skip(10).limit(20)
//先排序再分页
db.stock_movedetail.find({}).sort({"modifiedOn":1}).skip(10).limit(20)
//模糊查询
db.SellerCube.FMS.VoucherOperationRealize.VoucherEntity.find({ "DetailList.Abstract" :
/[ 仓 储\]\[内销/, "AccountantPeriodId" : 201512 });
不区分大小写的正则表达式
db.composite_skus.find({"baseInfo.description":{$regex:"XStandard",$options:"$i"}})
//$or 查询
db.stock_movemaster.find({$or:[{"Move_OutSureMan":"psx"},{"Move_InSureMan":"wgz hou"}]},{"Move_OutSureMan":1,"Move_InSureMan":1})
//$in 查询
db.stock_movedetail.find({"Move_BillNo":{$in:["MS060614002","MS060614002"]}},{"Mo ve_BillNo":1,_id:0})
时间查询嵌套查询

mongodb 索引的介绍与使用

MongoDB 的索引采用 BTree 结构,除了其地理位置索引外,数据索引本质上和
MySQL 的
BTree 索引没有什么差别,Mongodb 索引有如下几类:
单键索引:索引值为一个单一的值,比如字符串,更新日期等等。
唯一索引:哈唏索引:多建索引:索引值为多个值同时存在,例如数组。
复合索引:单键索引和多建索引的结合。
过期索引:在一段时间后会过期(自动销毁记录)的索引,适合用于处理用户登录信息等具有时间局限的记录过期处理(比较多的做法是 Session 或者 cookie),对一些存储日志的过期处理等等用途。
全文索引:主要用于搜索业务的索引,通过多种不同的查询方式和条件进行 MongoDB 全文索引,适合搜索引擎和站内搜索业务。
地理位置索引:根据区间值进行范围索引查询,这种索引适合于当前越来越流行的打车软件查询人车位置时通过索引提升查询效率,还有网购点餐时查询距离自己范围内的餐厅地址等等松散索引(稀疏索引):如果你的数据中一些行中没有某个字段或字段值为 null,那么如果在这个字段上建立普通索引,那么无此字段或值 null 的行也会参与到索引结构中,占用相应的空间。
如果我们不希望这些值为空的行参与到我们的索引中,这时候可以采用松散索引,松散索引只会让指定字段不为空的行参与到索引创建中来
在创建索引时注意如下:
5. 集合中索引不能超过 64 个
6. 索引名的长度不能超过 128 个字符
7. 一个复合索引最多可以有 31 个字段
如下是索引操作方法:

  • 单一索引
  • 唯一索引
db. stock_movemaster.ensureIndex({"sku_id":1},{unique: true}) db. stock_movemaster.ensureIndex({sku_id: 1}, {unique: true, dropDups: true}) 

如果你在一个已有数据的 collection 上创建唯一索引,若唯一索引对应的字段原来就有重复的数据项,那么创建会失败,我们需要加上一个 dropDups 的选项来强制将重复的项删除掉

  • 复合索引
db. stock_movemaster.ensureIndex({"id":1,name:1})

如果组合中的字符大于 127 个字符的话,会报错,这个时候需进行定义一个名称给这个索引了:

db. stock_movemaster.ensureIndex({"id":1,name:1}),{name:"mytName"});
  • 全文索引
db. stock_movemaster.ensureIndex({post_text:"text"}) 
- 使用全文索引
db. stock_movemaster.find({$text:{$search:"runoob"}})
  • 子文档索引如,users 表中有以下数据:
{name:"IT 笔录", address:{ city:"北京", district:"海淀区" }} 可以为 address 子文档创建索引如下:
db.users.ensureIndex({address:1})

建立索引后,查询时子文档的字段顺序要和查询顺序一致:

  • 会使用索引
    db.users.find({address:{ city:“北京”, district:“海淀区” }})
  • 不会使用索引
    db.users.find({address:{ district:“海淀区”, city:“北京” }})
    对子文档创建索引时,也可以只对某一个或几个字段创建索引:
    db.users.ensureIndex({“address.city”:1})
  • 松散索引
db.reviews.ensureIndex({user_id: 1}, {sparse: true})

关于稀疏索引。稀疏索引是仅包含有被索引字段的文档的索引,任何没有稀疏字段的文档都不会被存入该索引中

db.colB.ensureIndex({page: 1}, {sparse: true})

这个有什么用呢?比如一本书有一个 ISBN 字段,是不能重复的,也就是需要 unique 索引。但是假设现有数据中,有一些书没有这个数据,在存入 mongo 的过程中可能就是没有
ISBN
这个字段,或者字段值为 null,这样就没有办法用 unique 了,因为不唯一。这个时候就要
用到稀疏索引,

db.colA.createIndex({ISBN: 1}, {unique:1, sparse: 1}),

就能保证有 ISBN字段的值是唯一的。

  • 过期索引
    关于 expireAfterSeconds 有这么几点需要注意:
    • 创建 TTL 索引的这个字段,不能再创建其他索引
    • 索引不能包含多个字段
    • 索引字段必须是一个 bson 的日期类型,否则永远不会被自动删除
db.log_events.createIndex( { "expireAt": 1 }, { expireAfterSeconds: 3600 }



Mongodb 的聚合框架
https://docs.mongodb.com/manual/reference/operator/aggregation/out/

聚合框架中常用的几个操作:

$project:修改输入文档的结构。可以用来重命名、增加或删除域,也可以用于创建计算结果以及嵌套文档。
m a t c h : 用 于 过 滤 数 据 , 只 输 出 符 合 条 件 的 文 档 。 match:用于过滤数据,只输出符合条件的文档。 match:,match 使用 MongoDB 的标准查询操作。
$limit:用来限制 MongoDB 聚合管道返回的文档数。
$skip:在聚合管道中跳过指定数量的文档,并返回余下的文档。
$unwind:将文档中的某一个数组类型字段拆分成多条,每条包含数组中的一个值。
$group:将集合中的文档分组,可用于统计结果。 $sort:将输入文档排序后输出。
KaTeX parse error: Expected '}', got 'EOF' at end of input: …ter.aggregate({ project{“Move_BillNo”:1,“Move_FromStockID”:1,_id:
0}})
db.stock_movemaster.find({},{“Move_BillNo”:1,“Move_FromStockID”:1,_id:0}) //去重复数据
db.SellerCube.FMS.VoucherOperationRealize.VoucherEntity.aggregate([{ KaTeX parse error: Expected '}', got 'EOF' at end of input: …tantPeriodId":{ gte:201601},“Platform”:“仓储”}},
{ KaTeX parse error: Expected 'EOF', got '}' at position 24: …{VoucherName:1}}̲,{ group:{"_id":“KaTeX parse error: Expected 'EOF', got '}' at position 13: VoucherName"}̲}]) Mongodb3.4 …lookup 两集合关联查询方法
db.stock_movedetail.aggregate([
{
$lookup:
{
from:“stock_movemaster”, localField:“Move_BillNo”, foreignField:“Move_BillNo”,
as:“inventory_docs”
}
},
{ KaTeX parse error: Expected '}', got 'EOF' at end of input: … : {"Move_ID":{ lte:10}}},
{ KaTeX parse error: Expected 'EOF', got '}' at position 37: …ocs":1,"_id":0}}̲ ] ) // graphLookup 使用方法
https://docs.mongodb.com/manual/reference/operator/aggregation/graphLookup/
$ graphLookup 的单集合查询
/*
db.employees.insert({ “_id” : 1, “name” : “Dev” })
db.employees.insert({ “_id” : 2, “name” : “Eliot”, “reportsTo” : “Dev” }) db.employees.insert({ “_id” : 3, “name” : “Ron”, “reportsTo” : “Eliot” }) db.employees.insert({ “_id” : 4, “name” : “Andrew”, “reportsTo” : “Eliot” }) db.employees.insert({ “_id” : 5, “name” : “Asya”, “reportsTo” : “Ron” }) db.employees.insert({ “_id” : 6, “name” : “Dan”, “reportsTo” : “Andrew” })
/ /
db.employees.aggregate( [
{
KaTeX parse error: Expected '}', got 'EOF' at end of input: …", startWith: "reportsTo”, connectFromField: “reportsTo”, connectToField: “name”,
as: “reportingHierarchy”
}
},
{ KaTeX parse error: Expected 'EOF', got '}' at position 33: …ngHierarchy":1}}̲ ] ) /* // graphLookup 两个集合关联查询方法
db.airports.insert({ “_id” : 0, “airport” : “JFK”, “connects” : [ “BOS”, “ORD” ] }) db.airports.insert({ “_id” : 1, “airport” : “BOS”, “connects” : [ “JFK”, “PWM” ] }) db.airports.insert({ “_id” : 2, “airport” : “ORD”, “connects” : [ “JFK” ] }) db.airports.insert({ “_id” : 3, “airport” : “PWM”, “connects” : [ “BOS”, “LHR” ] })
db.airports.insert({ “_id” : 4, “airport” : “LHR”, “connects” : [ “PWM” ] })
/ /
db.travelers.insert({ “_id” : 1, “name” : “Dev”, “nearestAirport” : “JFK” }) db.travelers.insert({ “_id” : 2, “name” : “Eliot”, “nearestAirport” : “JFK” }) db.travelers.insert({ “_id” : 3, “name” : “Jeff”, “nearestAirport” : “BOS” })
/
/

db.travelers.aggregate( [
{
KaTeX parse error: Expected '}', got 'EOF' at end of input: …", startWith: "nearestAirport", connectFromField: “connects”,
connectToField: “airport”, maxDepth: 2, depthField: “numConnections”,
as: “destinations”
}
}
] )
//视图(Read-Only View)
一旦视图被创建,就可以对视图进行任何查询操作,操作内容和标准查询操作完全一致,而且可以继续进行聚合框架操作。但是切记,这是只读视图,不能写!当然,还是有些小小限制的,诸如不能用 MapReduce,不能用KaTeX parse error: Expected '}', got 'EOF' at end of input: …_movedetail",[{ project:{“Move_ID”:7}}])
//db.stock_movedetail_V.find();
//多集合创建视图
db.createView(“stock_movedetail_views”,“stock_movedetail”,[
{
$lookup:
{
from:“stock_movemaster”, localField:“Move_BillNo”, foreignField:“Move_BillNo”,
as:“inventory_docs”
}
},
{ KaTeX parse error: Expected '}', got 'EOF' at end of input: … : {"Move_ID":{ lte:10}}},
{$project:{“inventory_docs”:1,"_id":0}}
])
db.stock_movedetail_views.find()

扫描二维码关注公众号,回复: 12922462 查看本文章

猜你喜欢

转载自blog.csdn.net/yfanjy/article/details/108723965
今日推荐