首页 > 数据库 >mongodb

mongodb

时间:2022-11-22 15:47:29浏览次数:58  
标签:mongoHotel name mongodb db id 索引 find

mongodb

文档、非关系型数据数据库,底层索引结构使用的是B-树,只要找到它的子索引就可以进行访问,单次查询在结构上看是优于mysql,因为mysql是B+树

(1)B+树相邻接点的指针可以大大增加区间访问性,可使用在范围查询等,而B-树每个节点 key 和
data 在一起 适合随机读写 ,而区间查找效率很差。
(2)B+树更适合外部存储,也就是磁盘存储,使用B-结构的话,每次磁盘预读中的很多数据是用不上
的数据。因此,它没能利用好磁盘预读的提供的数据。由于节点内无 data 域,每个节点能索引的范围
更大更精确。
(3)注意这个区别相当重要,是基于(1)(2)的,B-树每个节点即保存数据又保存索引 树的深度大
小,所以磁盘IO的次数很少,B+树只有叶子节点保存,较B-树而言深度大磁盘IO多,但是区间访问比较
好。

基本操作语句

//查看所有集合
show collections;
//切换数据库
use xiaoy;
//查看当前操作的数据库
db;
//查询所有
db.mongoHotel.find();
db.mongoHotel.find({name: /全季/});
//排序
db.mongoHotel.find().limit(2).skip(2).sort({"score":-1});
//精准查询
db.mongoHotel.findOne({"city":"福建福州"});
//等于 == eq
db.mongoHotel.find({"city":{$eq: "上海"}});
//大于600
db.mongoHotel.find({ price : { $gt : 600,$lt : 1600}});
db.mongoHotel.find({ $or : [{city: "北京"},{city: "上海"}]});
//插入多个文档
db.mongoHotel.insertMany([{},{}],[{},{}])
//根据id查询
db.mongoHotel.findOne({"_id": 1});
//分页db.users.find().skip(页码-1 * 每页显示的条数).limit(每页显示的条数)   第一页,2条数据
db.mongoHotel.find().skip(1-1 * 2).limit(2);
//前10条数据
db.mongoHotel.find().limit(10);
//跳过前50条数据,即查询的是第61-70条数据,即第6页的数据
db.mongoHotel.find().skip(50).limit(10)
//设置查询结果的投影,即只过滤出自己想要的字段  1表示显示 0表示不显示
db.mongoHotel.find({},{city:1,address:1,_id:0}).explain();
//修改值$set
db.mongoHotel.updateOne({"name":" 福州全季酒店"},{"$set":{ "name":"福州全季酒店"}});
//删除指定字段$unset
db.mongoHotel.updateOne({"name":"福州全季酒店"},{"$unset":{"courses": "Dubbo"}});
//在某个文档新增字段
db.mongoHotel.updateOne({"name":"福州全季酒店"},{"$push":{"courses":"Dubbo"}});
//修改字段名
db.mongoHotel.updateOne({"name":"福州全季酒店"},{"$rename":{"pswd":"password"}});
//统计	
db.mongoHotel.find().count();
//对city进行分组,统计各个城市的文档值
db.mongoHotel.aggregate([{"$group":{"_id": "$city","num":{"$sum":1}}}]);
//获取索引
db.mongoHotel.getIndexes();

//所有文档新增字段
db.集合.updateMany({},{$set:{ "新字段": 0}})
    
//模糊查询
db.集合.find({name:{$regex:"^.*keyword.*$"}})

创建用户

db.createUser({
    user:"用户名",
    pwd:"密码",
    roles:[{
        role:"dbOwner", //用户权限
        db:"关联的数据库"
        }]
}
);

mongo原子操作

mongo无事务操作,不能要求它的完整性,它提供了多个原子操作,如:$set、$unset、$inc(加)、$push(减)等操作都是原子操作。

Update update=new Update();
        update.inc("filed");//+1

乐观锁

默认在修改删除操作时+1

//标识乐观锁字段
@Version
private Integer version;

分页操作

默认分页limit().skip()方式

db.mongoHotel.find().limit(2).skip(2).sort({"score":-1});

通过skip和limit方法可以简单的实现分页操作,但是如果数据量特别巨大的时候,会出现性能的问题,不建议使用

Pattern pattern = PatternFactory.getPattern(keyword);
Criteria criteria = Criteria.where("name").regex(pattern); //模糊查询
Query query = Query.query(criteria)
    .with(PageRequest.of(pageNum-1, pageSize))     //分页
    .with(Sort.by(Sort.Direction.DESC, "createTime")); //排序
mongoTemplate.find(query, 实体.class);

find().limit()方式

先查询10条,然后记录最后一个id记为lastId

Query query = new Query();
    query.with(PageRequest.of(page, size, Sort.by(Sort.Direction.DESC,"price")));
    query.with(Sort.by(Sort.Direction.DESC,"_id"));
    query.addCriteria(Criteria.where("_id").gt(new ObjectId(lastId)).limit(10);  
                      

注意使用ID进行范围查询时要 new ObjectId()

索引优化准则

  1. 根据ESR原则创建索引
    精确(Equal)匹配的字段放最前面,排序(Sort)条件放中间,范围(Range)匹配的字段放最后面,同样适用于ES,ER。
  2. 每一个查询都必须要有对应的索引
  3. 尽量使用覆盖索引 Covered Indexes(可以避免读数据文件)
    需要查询的条件以及返回值均在索引中
  4. 使用 projection 来减少返回到客户端的的文档的内容
  5. 尽可能不要计算总数,特别是数据量大和查询不能命中索引的时候
  6. 避免使用skip/limit形式的分页,特别是数据量大的时候

替代方案:使用查询条件+唯一排序条件
第一页:db.posts.find({}).sort({id: 1}).limit(20);

第二页:db.posts.find({_id: {![gt: <第一页最后一个_id>}}).sort(<第一页最后一个_id>}}).limit(20);

第三页:db.posts.find({gt: <第二页最后一个_id>}}).sort({_id: 1}).limit(20);

https://www.jianshu.com/p/36599a0011c9

MongoDB索引类型

MongoDB 支持多种类型的索引,包括单字段索引、复合索引、多 key 索引、文本索引等,每种类型的索引有不同的使用场合。

  • 单字段索引:_id;
  • 复合索引:有多个字段需要建索引的场景,多个索引字段的组合;
  • 多 key 索引:一般使用场合为字段是对象场景,会给改对象字段里的每个字段自动加索引;

复合索引字段先后顺序

age 字段的取值很有限,即拥有相同 age 字段的文档会有很多;而 name 字段的取值则丰富很多,拥有相同 name 字段的文档很少;显然先按 name 字段查找,再在相同 name 的文档里查找 age 字段更为高效。

创建索引

(通俗理解)其实就是在数据的底层给这个字段加一个位置标识,并排序好,这样下次搜索是根据标识去搜索,就像你给sql语句加了一个where条件类似。

db.table_Name.createIndex( {field: 1|-1 ,filed1:1} )         // 单个字段建立索引 、联合索引	
      
db.table_name.createIndex({filed: "text"},{name: "索引别名"});   // 单个字段建立 全文索引  

db.table_name.createIndex({"实体类.属性":1});    //创建子文档索引

1升序排序,-1降序排序

注:创建索引会阻塞,在创建过程中是无法对集合进行读写操作。

查看当前几个所有索引

db.table_name.getIndexes()

explain

db.table_Name.find({query}).explain(cond)

winningPlan.stage: IXSCAN 表示走索引

COLLSCAN: 全表扫描

stage(阶段)
COLLSCAN 全表扫描
IXSCAN 索引扫描
FETCH 根据索引去检索文档
SHARD_MERGE 合并分片结果
IDHACK 针对 _id 进行查询

强制使用索引

db.table_name.find({query}).hint({"index_name":1});//强制使用索引

字段维护

db.video_info.updateMany({},{"$unset":{
    "aliStatus": null     //删除aliStatus字段
}});

db.video_info.updateMany({},{"$set":{
    "aliStatus": 0        //新增字段加默认值
}});

db.video_info.updateMany({},{"$rename":{"pswd":"password"}}); //改字段名

mongodb:objectId理解

MongoDB的文档固定是使用"_id"作为主键的,ObjectId使用12字节的存储空间,每个字节两位十六进制数字,是一个24位的字符串

image-20220908143417613

前4为时间戳隐含了文档的创建时间

mongodb分片机制

存储容量需求超出了单机磁盘容量,需要分片来横向扩展

数据分部策略:mongos也会根据各个shard上的chunk的数量来自动做[负载均衡]

范围分片:根据查找值在范围内的数据进行分片

范围分片缺点 如果shardkey有明显递增(或者递减)趋势,则新插入的文档多会分布到同一个chunk,无法扩展写的能力

hash分片:Hash分片是根据用户的shard key计算hash值(64bit整型),根据hash值按照『范围分片』的策略将文档分布到不同的chunk

hash分片优点:Hash分片与范围分片互补,能将文档随机的分散到各个chunk,充分的扩展写能力,弥补了范围分片的不足

hash分片缺点:但不能高效的服务范围查询,所有的范围查询要分发到后端所有的Shard才能找出满足条件的文档。(需要合理的选择shard key)

分组聚合查询

db.表.aggregate([{
    $group: {
        "_id": "$分组字段",
        "统计别名": {
            "$sum": 1
            }
          }
    },
{
   $project: {
        "分组字段": "$_id",
        "统计别名": 1,
        "_id": 0  //id不显示
    }
}])
List<AggregationOperation> operations=new ArrayList<>();
MatchOperation matchOperation = Aggregation.match(Criteria.where("筛选条件").in(ids));
GroupOperation groupOperation = Aggregation.group("分组字段").count().as("别名");
ProjectionOperation projectionOperation = Aggregation.project("需要的字段","分组字段别名").and("分组字段").previousOperation();
operations.add(groupOperation);
operations.add(projectionOperation);
TypedAggregation<VideoComment> videoCommentTypedAggregation = Aggregation.newAggregation(
                VideoComment.class, operations);


.and("分组字段").previousOperation();  //的意思是将_id转换为parentId        

标签:mongoHotel,name,mongodb,db,id,索引,find
From: https://www.cnblogs.com/daoping/p/16915281.html

相关文章

  • Spring Data (数据)MongoDB(二)
    10.6.查询文档您可以使用theandclasses来表达您的查询。它们具有反映本机MongoDB运算符名称的方法名称,例如,,,等。Theandclasses遵循流畅的API样式,因此您可以将多个方......
  • Spring Data (数据)MongoDB(三)
    10.21.更改流从MongoDB3.6开始,ChangeStreams允许应用程序获得有关更改的通知,而无需跟踪oplog。更改流支持仅适用于副本集或分片集群。更改流可以与命令式和反应式MongoDB......
  • Spring Data (数据)MongoDB
    版本4.0.0SpringDataMongoDB项目将Spring的核心概念应用于使用MongoDB文档样式数据存储的解决方案的开发。我们提供了一个“模板”作为存储和查询文档的高级抽象。您可能......
  • MongoDB Server 用户名和密码登录
    MongoDBServer用户名和密码登录一、前言默认情况下,MongoDB实例启动运行时是没有启用用户访问权限控制的,也就是说,在实例本机服务器上都可以随意连接到实例进行各种操作,M......
  • WGCLOUD v3.4.2 配置使用监测 MongoDB 教程
    WGCLOUD是一款高效轻量的运维平台它可以监测各种数据库的运行状态,如果出现连不上的情况,也会及时告警,比如SQLServer、Oracle、MySQL、PostgreSQL、Redis等,我们就看下它怎么......
  • mongodb后台守护进程启动
    Mongodb可以通过命令行方式和配置文件的方式来启动,具体命令如下:命令行: Shell代码1.[root@localhostmongodb]#./bin/mongod--dbpath=/data/db配置文件:Shell代码1.[......
  • mongodb windows 安装以及资料
    mongoDBwindows安装1:下载http://www.mongodb.org/display/DOCS/Downloads选择你要下载的版本解压软件包,你会看到解压后的文件夹中有个BIN目录,进......
  • MongoDB快速开始(V6.0)
    1.切换数据库显示当前数据库db切换数据库useexamples2.插入文档MongoDBstoresdocumentsincollections.Collectionsareanalogoustotablesinrelation......
  • Debian 11上安装MongoDB 5
    关闭numa和transparent_hugepage$sudovi/etc/default/grub添加GRUB_CMDLINE_LINUX_DEFAULT="quietinuma=offtransparent_hugepage=never"$sudogrub-mkconfig......
  • MongoDB - 索引知识
    索引简介什么是索引索引最常用的比喻就是书籍的目录,查询索引就像查询一本书的目录。索引支持MongoDB查询的高效执行。如果没有索引,MongoDB必须扫描集合中每一个文档,......