“MongoDB基础知识【超详细】


"探索MongoDB的无边之境:沉浸式数据库之旅"

欢迎来到MongoDB的精彩世界!在这个博客中,我们将带您进入一个充满创新和无限潜力的数据库领域。无论您是开发者、数据工程师还是技术爱好者,MongoDB都将为您带来一场令人心动的沉浸式体验。

从一开始,我们将揭开MongoDB的神秘面纱,告诉您为什么它成为当今数据库领域的明星。您将发现MongoDB的灵活性和可扩展性如何颠覆传统数据库的概念,让您摆脱约束,以自由自在的方式处理数据。

在这个博客中,我们将带您深入了解MongoDB的架构和设计原理。您将探索文档型数据模型的魅力,学习如何利用无模式设计存储和查询各种类型的数据。我们还会分享一系列最佳实践、技巧和性能优化策略,让您的MongoDB应用发挥出最大的潜力。

不仅如此,我们将通过实际案例和故事,向您展示MongoDB如何在真实世界中发挥作用。您将了解到它如何助力起步公司快速迭代和扩展业务,如何帮助大型企业应对海量数据的挑战,以及如何在物联网和人工智能领域掀起革命性的变革。

无论您是MongoDB的新手还是有经验的专家,这个博客都将成为您掌握MongoDB的绝佳资源。加入我们,追寻MongoDB的无边之境,开启一段令人兴奋的数据库之旅吧!

基础知识

概述

MongoDB

简介
MongoDB是免费开源的跨平台NoSQL数据库,以BSON格式存储

BSON
BSON是一种类似于JSON的二进制形式的存储格式,简称Binary JSON
它和JSON一样,支持内嵌的文档对象和数组对象,但是BSON有JSON没有的一些数据类型,如Date和BinData类型
BSON有三个特点:轻量性、可遍历性、高效性

应用场景

适用场景
网站数据:Mongo 非常适合实时的插入,更新与查询,并具备网站实时数据存储所需的复制及高度伸缩性
缓存:由于性能很高,Mongo 也适合作为信息基础设施的缓存层。在系统重启之后,由Mongo搭建的持久化缓存层可以避免下层的数据源过载
大尺寸、低价值的数据:使用传统的关系型数据库存储一些大尺寸低价值数据时会比较浪费,在此之前,很多时候程序员往往会选择传统的文件进行存储
高伸缩性的场景:Mongo 非常适合由数十或数百台服务器组成的数据库,Mongo 的路线图中已经包含对MapReduce 引擎的内置支持以及集群高可用的解决方案
用于对象及JSON数据的存储:Mongo的BSON数据格式非常适合文档化格式的存储及查询

具体应用
游戏场景:使用MongoDB存储游戏用户信息,用户的装备、积分等直接以内嵌文档的形式存储,方便查询、更新
物流场景:使用MongoDB存储订单信息,订单状态在运送过程中会不断更新,以MongoDB内嵌数组的形式来存储,一次查询就能将订单所有的变更读取出来
社交场景:使用MongoDB存储存储用户信息,以及用户发表的朋友圈信息,通过地理位置索引实现附近的人、地点等功能
物联网场景:使用MongoDB存储所有接入的智能设备信息,以及设备汇报的日志信息,并对这些信息进行多维度的分析
直播:使用MongoDB存储用户信息、礼物信息等

逻辑结构

简介
MongoDB与MySQL中的架构相差不多,底层都使用了可插拔的存储引擎以满足用户的不同需要,用户可以根据程序的数据特征选择不同的存储引擎
在存储引擎上层的就是MongoDB的数据模型和查询语言

数据模型

简介
与SQL数据库不同,在SQL数据库中,在插入数据之前必须确定和声明表的架构
默认情况下,MongoDB的集合不要求其文档具有相同的架构

结构灵活
单个集合中的文档不需要具有相同的字段集合,并且集合中的文档之间的字段数据类型可能不同;
可灵活更改集合中文档的结构,如添加新字段、删除现有字段或将字段值更改为新类型,将文档更新为新结构。

文档结构【内嵌】
内嵌的方式指的是把相关联的数据保存在同一个文档结构之中
MongoDB的文档结构允许一个字段或者一个数组内的值作为一个嵌套的文档

文档结构【引用】
引用方式通过存储数据引用信息来实现两个不同文档之间的关联,应用程序可以通过解析这些数据引用来访问相关数据

WiredTiger存储引擎

简介
从MongoDB 3.2开始默认的存储引擎是WiredTiger,3.2版本之前的默认存储引擎是MMAPv1,MongoDB 4.x版本不再支持MMAPv1存储引擎
WiredTiger提供了不同粒度的并发控制和压缩机制,能够为不同种类的应用提供了最好的性能和存储率

支持document级别并发操作
WiredTiger对写入操作使用document级并发控制。因此,多个客户端可以同时修改集合的不同文档
对于大多数读写操作,WiredTiger使用乐观并发控制。WiredTiger仅在全局、数据库和集合级别使用意向锁
当存储引擎检测到两个操作之间的冲突时,其中一个操作将引发写入冲突,MongoDB会对用户透明地重试该操作

快照和检查点
WiredTiger使用多版本并发控制(MVCC)
在操作开始时,WiredTiger会向操作提供数据的point-in-time快照,快照显示了数据在内存中的一致性视图
从3.6版开始,MongoDB将WiredTiger配置为每隔60秒创建检查点(即将快照数据写入磁盘)
在早期版本中,MongoDB将检查点设置为在WiredTiger中每隔60秒或写入2 GB日志数据时(以先发生的为准)对用户数据进行检查

日志
WiredTiger将日志与检查点结合使用,以确保数据的持久性
WiredTiger日志将保留检查点之间的所有数据修改
如果MongoDB在两个检查点之间退出,它将使用日志重播自上一个检查点以来修改的所有数据

压缩
使用WiredTiger存储引擎,MongoDB会对所有集合和索引进行压缩,压缩以牺牲额外的CPU为代价,最大限度地减少了磁盘的使用
默认情况下,WiredTiger对所有集合使用block compression,并对索引使用prefix compression

内存使用
对于WiredTiger,MongoDB利用WiredTiger内部缓存和文件系统缓存
从MongoDB 3.4开始,默认WiredTiger内部缓存大小为以下两者中的较大值:
50% of (RAM - 1 GB)
256 MB
          

In-memory存储引擎

简介
从MongoDB 企业版3.2.6版开始,In-Memory存储引擎是64位版本中广泛使用(general availability GA)的一部分
除某些元数据和诊断数据外,In-Memory存储引擎不维护任何磁盘上的数据,包括配置数据,索引,用户凭据等

In-Memory存储引擎设置
配置--storageEngine选项值为inMemory;如果使用配置文件,则配置storage.engine
配置--dbpath,如果使用配置文件则配置storage.dbPath。尽管In-Memory存储引擎不会将数据写入文件系统,
但它会在--dbpath中维护小型元数据文件和诊断数据以及用于构建大型索引的临时文件
mongod --storageEngine inMemory --dbpath


并发
In-Memory存储引擎对于写入操作使用了document级并发控制
多个客户端可以同时修改集合的不同文档

内存使用
默认情况下,In-Memory存储引擎使用50%的物理RAM减去1GB
如果写操作的数据超过了指定的内存大小,则MongoDB返回错误:
"WT_CACHE_FULL: operation would overflow cache"
要指定新大小,可使用YAML格式配置文件的

事务
从MongoDB 4.2开始,复制集和分片集群上支持事务,其中:
主成员节点使用WiredTiger存储引擎,同时,辅助成员使用WiredTiger存储引擎或In-Memory存储引擎
在MongoDB 4.0中,只有使用WiredTiger存储引擎的复制集才支持事务
          

安装

yum安装

安装
进入/etc/yum.repos.d目录,创建文件mongodb-org-5.0.repo

cd /etc/yum.repos.d

vim mongodb-org-5.0.repo

[mongodb-org]
name=MongoDB Repository
baseurl=http://mirrors.aliyun.com/mongodb/yum/redhat/7Server/mongodb-org/5.0/x86_64/
gpgcheck=0
enabled=1


更新yum

yum update


安装

yum -y install mongodb-org


修改配置文件
查看mongo的安装位置

whereis mongod


修改配置文件

vim /etc/mongod.conf


bindIp: 172.0.0.1 改为 bindIp: 0.0.0.0

mongdb的使用
查看

systemctl status mongod.service


启动

systemctl start mongod.service


停止

systemctl stop mongod.service


重启
systemctl restart mongod.service查看

systemctl status mongod.service


设置开机自启动

systemctl enable mongod.service



mongo shelld的使用
启动

cd /usr/bin

./mongo



启动【指定主机和端口】

cd /usr/bin

./mongo--host=主机IP --port=端口


          

docker安装

安装
拉取镜像

docker pull mongo:4.4.14-focal


创建容器

docker run -itd --name mongo -p 8036:27017  mongo:4.4.14-focal --auth



配置管理员
进入容器

docker exec -it mongo bash


进入终端

mongo


进入admin数据库

use admin


创建管理员账户

db.createUser({ user: "root", pwd: "Jiakewei521", roles: [{ role: "root", db: "admin" }] })


验证用户添加是否成功

db.auth("root", "Jiakewei521");


如果返回1,则表示成功

进入终端
进入容器

docker exec -it mongo bash


进入终端

mongo


以管理员身份登录

use admin

switched to db admin
db.auth("root","Jiakewei521")

安全认证

MongoDB安全认证

简介
MongoDB 默认是没有账号的,可以直接连接,无须身份验证,但实际项目中肯定是要权限验证的,否则后果不堪设想

认证相关操作
docker以auth方式创建MongoDB容器

docker run -itd --name mongo5 -p 27017:27017 mongo:xxx --auth



备份数据

mongodump -h 127.0.0.1:27017 -d mydb -o /usr/local



恢复数据(在用户认证之后)

mongorestore -h localhost -u root -p 123456 --db mydb /dump/mydb --authenticationDatabase admin


        

基于角色的访问控制相关知识

用户命令
修改密码

db.changeUserPassword( '账号' , '密码' );


添加角色

db.grantRolesToUser('用户名',[{ role:'角色名', db:'数据库名'}])


删除用户

db.dropUser("用户名")


验证用户【返回 1 说明认证成功】

db.auth("账号","密码")



内置角色
root    超级账号,超级权限
read    允许用户读取指定数据库
readwrite    允许用户读写指定数据库
dbAdmin    可以读取任何数据库并对库进行清理、修改、压缩,获取统计信息、执行检查等操作
userAdmin    可以在指定数据库里创建、删除和管理用户
readAnyDatabase    可以读取任何数据库中的数据,除了数据库config和local之外
readwriteAnyDatabase    可以读写任何数据库中的数据,除了数据库config和local之外
userAdminAnyDatabase    可以在指定的数据库中创建和修改用户,除了数据库config和local之外
dbAdminAnyDatabase    可以读取任何数据库并对库进行清理、修改、压缩,获取统计信息、执行检查等操作,除了数据库config和local之外
backup    备份数据权限
restore    从备份中恢复数据的权限

mongdb中用户默认对应的角色
数据库用户    read、readwrite
数据库管理角色    dbAdmin、userAdmin
所有数据库角色    readAnyDatabase、readWriteAnyDatabase、userAdminAnyDatabase、 dbAdminAnyDatabase
备份恢复角色    backup、restore
超级用户角色    root
         

管理员

创建管理员
MongoDB 服务端开启安全检查之前,至少需要有一个管理员账号,admin 数据库中的用户都被视为管理员
如果 admin 库没有任何用户的话,即使在其他数据库中创建了用户,启用身份验证,
默认的连接方式依然会有超级权限,即仍然可以不验证账号密码照样能进行 CRUD,安全认证相当于无效
进入容器

docker exec -it mongo bash


进入终端

mongo


进入admin数据库

use admin


创建管理员账户

db.createUser({ user: "root", pwd: "Jiakewei521", roles: [{ role: "root", db: "admin" }] })


验证用户添加是否成功

db.auth("root", "Jiakewei521");


如果返回1,则表示成功

管理员登录
客户端管理员以root用户登录,安全认证通过后,拥有对所有数据库的所有权限
进入容器

docker exec -it mongo bash


进入终端

mongo


以管理员身份登录

use admin
switched to db admin
db.auth("root","Jiakewei521")


        

普通用户

创建普通用户
创建mydb数据库并创建两个用户,zhangsan 拥有读写权限,lisi 拥有只读权限测试这两个账户的权限。以超级管理员登录测试权限

> use mydb
switched to db mydb
>  db.c1.insert({name:"testdb1"})
WriteResult({ "nInserted" : 1 })
> db.c2.insert({name:"testdb1"})
WriteResult({ "nInserted" : 1 })
> show tables
c1
c2
> db.c1.find()
{ "_id" : ObjectId("62a00e5c1eb2c6ab85dd5eec"), "name" : "testdb1" }
> db.c1.find({})
{ "_id" : ObjectId("62a00e5c1eb2c6ab85dd5eec"), "name" : "testdb1" }
> show dbs
admin   0.000GB
config   0.000GB
local   0.000GB
mydb    0.001GB
>

普通用户登录
普通用户现在仍然像以前一样进行登录,如下所示直接登录进入 mydb数据库中,登录是成功的,只是登录后日志少了很多东西,
而且执行 show dbs 命令,以及 show tables 等命令都是失败的,即使没有被安全认证的数据库,用户同样操作不了,
这都是因为权限不足,一句话:用户只能在自己权限范围内的数据库中进行操作

> db.auth("zhangsan","123456")
1
> show dbs
mydb 0.001GB
> show tables
c1
c2        
        

常用命令

数据库命令

查看数据库

show dbs;



切换数据库 如果没有对应的数据库则创建

use 数据库名;



创建集合

db.createCollection("集合名")



查看集合

showtables;
show collections;



删除集合

db.集合名.drop();



删除当前数据库

db.dropDatabase();


        

添加文档

注意
添加单个文档,如果集合不存在,会创建一个集合
如果不指定id, MongoDB会使用ObjectId的value作为id

添加单个文档

db.inventory.insertOne(
{ item: "canvas", qty: 100, tags: ["cotton"], size: { h: 28, w: 35.5, uom: "cm" } })



添加多个文档

db.inventory.insertMany([
{ item: "journal", qty: 25, tags: ["blank", "red"], size: { h: 14, w: 21, uom: "cm" } },
{ item: "mat", qty: 85, tags: ["gray"], size: { h: 27.9, w: 35.5, uom: "cm" } },
{ item: "mousepad", qty: 25, tags: ["gel", "blue"], size: { h: 19, w: 22.85, uom: "cm" }}])    

更新文档

测试数据

db.inventory.insertMany( [
{ item: "canvas", qty: 100, size: { h: 28, w: 35.5, uom: "cm" }, status: "A" },
{ item: "journal", qty: 25, size: { h: 14, w: 21, uom: "cm" }, status: "A" },
{ item: "mat", qty: 85, size: { h: 27.9, w: 35.5, uom: "cm" }, status: "A" },
{ item: "mousepad", qty: 25, size: { h: 19, w: 22.85, uom: "cm" }, status: "P" },
{ item: "notebook", qty: 50, size: { h: 8.5, w: 11, uom: "in" }, status: "P" },
{ item: "paper", qty: 100, size: { h: 8.5, w: 11, uom: "in" }, status: "D" },
{ item: "planner", qty: 75, size: { h: 22.85, w: 30, uom: "cm" }, status: "D" },
{ item: "postcard", qty: 45, size: { h: 10, w: 15.25, uom: "cm" }, status: "A" },
{ item: "sketchbook", qty: 80, size: { h: 14, w: 21, uom: "cm" }, status: "A" },
{ item: "sketch pad", qty: 95, size: { h: 22.85, w: 30.5, uom: "cm" }, status: "A" }] );



操作1
更新item值为“paper”的第一个文档 将它的size.uom设置为“cm”,status值设置为"P"
并且把lastModified字段更新为当前时间,如果该字段不存在,则生成一个

db.inventory.updateOne(
{ item: "paper" },
{$set: { "size.uom": "cm", status: "P" },
$currentDate: { lastModified: true }}
)



操作2
更新qty属性值小于50的文档 将它的size.uom设置为“in”,status值设置为"P"
并且把lastModified字段更新为当前时间,如果该字段不存在,则生成一个

把item属性为“paper”的文档替换成下面的内容

db.inventory.replaceOne(
{ item: "paper" },{ item: "paper", instock: [ { warehouse: "A", qty: 60 }, { warehouse: "B", qty: 40 } ] })

删除文档

删除集合所有文档

db.inventory.deleteMany({})



删除指定条件的文档

db.inventory.deleteMany({ status : "A" })



最多删除1个指定条件的文档

db.inventory.deleteOne( { status: "D" } )

查询文档

测试数据

db.inventory.insertMany( [
{ item: "journal", qty: 25, size: { h: 14, w: 21, uom: "cm" }, status: "A" },
{ item: "notebook", qty: 50, size: { h: 8.5, w: 11, uom: "in" }, status: "A" },
{ item: "paper", qty: 100, size: { h: 8.5, w: 11, uom: "in" }, status: "D" },
{ item: "planner", qty: 75, size: { h: 22.85, w: 30, uom: "cm" }, status: "D" },
{ item: "postcard", qty: 45, size: { h: 10, w: 15.25, uom: "cm" }, status: "A" }
]);



查询集合所有文档

db.inventory.find({})



查询指定内容的文档【size内容顺序要匹配】

db.inventory.find( { size: { h: 14, w: 21, uom: "cm" } } )



匹配size中uom属性为“in”的文档

db.inventory.find( { "size.uom": "in" } )



匹配size中h属性值小于15的文档

db.inventory.find( { "size.h": { $lt: 15 } } )



匹配h属性小于15并且uom属性为“in”,并且“status”属性为"D"的文档

db.inventory.find( { "size.h": { $lt: 15 }, "size.uom": "in", status: "D" } )

聚合命令

聚合操作

聚合操作
通过聚合操作可以处理多个文档,并返回计算后的结果:对多个文档进行分组/对分组的文档执行操作并返回单个结果/分析数据变化

聚合管道
分别由多个阶段来处理文档,每个阶段的输出是下个阶段的输入,返回的是一组文档的处理结果
例如,total、average、maxmium、minimium

测试数据

db.orders.insertMany([
{ _id: 0, name: "Pepperoni", size: "small", price: 19,quantity: 10, date: ISODate( "2030-03-13T08:14:30Z" ) },
{ _id: 1, name: "Pepperoni", size: "medium", price: 20,quantity: 20, date : ISODate( "2030-03-13T09:13:24Z" ) },
{ _id: 2, name: "Pepperoni", size: "large", price: 21,quantity: 30, date : ISODate( "2030-03-17T09:22:12Z" ) },
{ _id: 3, name: "Cheese", size: "small", price: 12,quantity: 15, date : ISODate( "2030-03-13T11:21:39.736Z" ) },
{ _id: 4, name: "Cheese", size: "medium", price: 13,quantity:50, date : ISODate( "2031-01-12T21:23:13.331Z" ) },
{ _id: 5, name: "Cheese", size: "large", price: 14,quantity: 10, date : ISODate( "2031-01-12T05:08:13Z" ) },
{ _id: 6, name: "Vegan", size: "small", price: 17,quantity: 10, date : ISODate( "2030-01-13T05:08:13Z" ) },
{ _id: 7, name: "Vegan", size: "medium", price: 18,quantity: 10, date : ISODate( "2030-01-13T05:10:13Z" ) }
])



示例1
计算尺寸为medium的订单中,每种类型的订单数量

db.orders.aggregate( [
// Stage 1: 匹配size:"medium"的文档
{
$match: { size: "medium" }
},
// Stage 2: 根据name统计过滤后的文档,并把"quantity"值相加
{
$group: { _id: "$name", totalQuantity: { $sum: "$quantity" } }
}
] )



示例2
更复杂的例子

db.orders.aggregate( [
// Stage 1: 根据日期范围过滤
{
$match:
{
"date": { $gte: new ISODate( "2030-01-01" ), $lt: new ISODate( "2030-01-30" ) }
}
},
// Stage 2: 对过滤后文档以日期为条件进行分组并计算
{
$group:
{
_id: { $dateToString: { format: "%Y-%m-%d", date: "$date" } },
totalOrderValue: { $sum: { $multiply: [ "$price", "$quantity" ] } },
averageOrderQuantity: { $avg: "$quantity" }
}
},
// Stage 3: 按照订单价值倒序排列文档
{
$sort: { totalOrderValue: -1 }
}
] )  


          

聚合管道顺序优化

聚合管道顺序优化
聚合管道在执行的过程中有一个优化的阶段,以提高性能

优化前

$addFields: {
maxTime: { $max: "$times" },
minTime: { $min: "$times" }
} },
{ $project: {
_id: 1, name: 1, times: 1, maxTime: 1, minTime: 1,
avgTime: { $avg: ["$maxTime", "$minTime"] }
} },
{ $match: {
name: "Joe Schmoe",
maxTime: { $lt: 20 },
minTime: { $gt: 5 },
avgTime: { $gt: 7 }
} }




优化后
优化思路:优化器把$match阶段分成了4个独立的过滤器,尽可能把过滤器放在$project操作前面,优化后的聚合管道如下

{ $match: { name: "Joe Schmoe" } },
{ $addFields: {
maxTime: { $max: "$times" },
minTime: { $min: "$times" }
} },
{ $match: { maxTime: { $lt: 20 }, minTime: { $gt: 5 } } },
{ $project: {
_id: 1, name: 1, times: 1, maxTime: 1, minTime: 1,
avgTime: { $avg: ["$maxTime", "$minTime"] }
} },
{ $match: { avgTime: { $gt: 7 } } }


            

索引命令

索引

简介
索引是一种单独的、物理的对数据库表中一列或多列的值进行排序的一种存储结构
索引是某个表中一列或若干列值的集合和相应的指向表中物理标识这些值的数据页的逻辑指针清单

作用
相当于图书的目录,可以根据目录中的页码快速找到所需的内容
提高数据库的查询效率,没有索引的话,查询会进行全表扫描,数据量大时严重降低了查询效率
          

索引管理

获取索引

db.collection.getIndexes()



获取索引数量

db.collection.totalIndexSize()



重建索引

db.collection.reIndex()



删除索引
注意: _id 对应的索引是删除不了的

db.collection.dropIndex("INDEX-NAME")
db.collection.dropIndexes()            

单键索引

简介
MongoDB默认所有的集合在_id字段上有一个索引

创建索引
注意:1代表升序,-1代表降序
创建索引:db.test.createIndex( { key字段: 1 } )
创建索引【有内嵌字段】:db.test.createIndex( { "key字段.子key字段": 1 } )
创建复合索引:db.test.createIndex( { "key字段.子key字段": 1 ,"key字段.子key字段": 1...} )

创建复合

示例
示例数据

db.test.inseartOne({
"_id": 123,
"score": 356,
"location": { province: "Hebei", city: "Tangshan" }
})


创建索引

db.test.createIndex( { score: 1 } )


创建内嵌字段的索引

db.test.createIndex( { "location.province": 1 } )


创建复合索引

db.test.createIndex( {score: 1, "location.province": 1 } )

多键索引

简介
多键索引用于为数组中的元素创建索引

示例
测试数据

[{ _id: 5, type: "food", item: "aaa", ratings: [ 5, 8, 9 ] },
{ _id: 6, type: "food", item: "bbb", ratings: [ 5, 9 ] },
{ _id: 7, type: "food", item: "ccc", ratings: [ 9, 5, 8 ] },
{ _id: 8, type: "food", item: "ddd", ratings: [ 9, 5 ] },
{ _id: 9, type: "food", item: "eee", ratings: [ 5, 9, 5 ] }]



创建多键索引

db.inventory.createIndex( { ratings: 1 } )


原理解释:
MongoDB使用多键索引查找在“ratings”数组中有“5”的文档,
然后,MongoDB检索这些文档并筛选“ratings”数组等于查询数组“[5,9]”的文档

地理空间索引

地理空间索引
针对地理空间坐标数据创建索引。2dsphere索引用于存储和查找球面上的点,2d索引用于存储和查找平面上的点

db.company.insert(
{
loc : { type: "Point", coordinates: [ 116.502451, 40.014176 ] },
name: "军博地铁",
category : "Parks"
}
)


 

db.company.createIndex( { loc : "2dsphere" } )


 

db.company.find({
"loc" : {
"$geoWithin" : {
"$center":[[116.482451,39.914176],0.05]
}
}
})


 

db.places.insert({"name":"aa","addr":[32,32]})
db.places.insert({"name":"bb","addr":[30,22]})
db.places.insert({"name":"cc","addr":[28,21]})
db.places.insert({"name":"dd","addr":[34,26]})
db.places.insert({"name":"ee","addr":[34,27]})
db.places.insert({"name":"ff","addr":[39,28]})


 

db.places.find({})
db.places.createIndex({"addr":"2d"})
db.places.find({"addr":{"$within":{"$box":[[0,0],[30,30]]}}})

全文索引

全文索引
MongoDB提供了针对string内容的文本查询,Text Index支持任意属性值为string或string数组元素的索引查询
注意:一个集合仅支持最多一个Text Index,中文分词不理想推荐ES
 

db.fullText.insert({name:"aa",description:"no pains,no gains"})
db.fullText.insert({name:"ab",description:"pay pains,get gains"})
db.fullText.insert({name:"ac",description:"a friend in need,a friend in deed"})



创建索引并指定语言

db.fullText.createIndex(
{ description : "text" },
{ default_language: "english" }
)

db.fullText.find({"$text": {"$search": "pains"}})



全文索引名称

db.collection.createIndex(
{
content: "text",
"users.comments": "text",
"users.profiles": "text"
}
)


生成的默认索引名:content_text_users.comments_text_users.profiles_text

指定名称

db.collection.createIndex(
{
content: "text",
"users.comments": "text",
"users.profiles": "text"
},
{
name: "MyTextIndex"
}
)



使用指定名称删除索引

db.collection.dropIndex("MyTextIndex")


          

哈希索引

哈希索引
针对属性的哈希值进行索引查询,当要使用Hashed index时,MongoDB能够自动的计算hash值,
无需程序计算hash值。注:hash index仅支持等于查询,不支持范围查询
 

db.collection.createIndex({"field": "hashed"})


创建复合hash索引,4.4以后的版本

db.collection.createIndex( { "fieldA" : 1, "fieldB" : "hashed", "fieldC" : -1 } )

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/92736.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

PLY模型格式详解【3D】

本文介绍PLY 多边形文件格式,这是一种用于存储被描述为多边形集合的图形对象。 PLY文件格式的目标是提供一种简单且易于实现但通用的格式足以适用于各种模型。 PLY有两种子格式:易于入门的 ASCII 表示形式和用于紧凑存储和快速保存和加载的二进制格式。 …

搭建 Python 环境 | Python、PyCharm

计算机 计算机能完成的工作: 算术运算逻辑判断数据存储网络通信…更多的更复杂的任务 以下这些都可以称为 “计算机”: 一台计算机主要由以下这几个重要的组件构成 CPU 中央处理器:大脑,算术运算,逻辑判断 存储器&…

Redis——常见数据结构与单线程模型

Redis中的数据结构 Redis中所有的数据都是基于key,value实现的,这里的数据结构指的是value有不同的类型。 当前版本Redis支持10种数据类型,下面介绍常用的五种数据类型 底层编码 Redis在实现上述数据结构时,会在源码有特定的…

Docker数据卷容器

1.数据卷容器介绍 即使数据卷容器c3挂掉也不会影响c1和c2通信。 2.配置数据卷容器 创建启动c3数据卷容器,使用-v参数设置数据卷。volume为目录,这种方式数据卷目录就不用写了,直接写宿主机目录。 创建c1、c2容器,使用–volum…

三星霸主地位“无可撼动“,DRAM内存市场份额创近 9 年新低仍第一

三星电子在DRAM市场的竞争地位一直备受关注。据报告显示,除了市场份额下降外,三星电子在上半年的销售额也出现了下滑。这主要是由于全球消费电子产品需求下滑,导致三星电子的芯片需求减少。 存储芯片业务所在的设备解决方案部门的营收和利润也…

24届近3年上海电力大学自动化考研院校分析

今天给大家带来的是上海电力大学控制考研分析 满满干货~还不快快点赞收藏 一、上海电力大学 学校简介 上海电力大学(Shanghai University of Electric Power),位于上海市,是中央与上海市共建、以上海市管理为主的全日…

经典人体模型SMPL介绍(一)

SMPL是马普所提出的经典人体模型,目前已成为姿态估计、人体重建等领域必不可少的基础先验。SMPL基于蒙皮和BlendShape实现,从数千个三维人体扫描结果得来,后通过PCA统计学习得来。 论文:SMPL: A Skinned Multi-Person Linear Mode…

基于Python的HTTP代理爬虫开发初探

前言 随着互联网的发展,爬虫技术已经成为了信息采集、数据分析的重要手段。然而在进行爬虫开发的过程中,由于个人或机构的目的不同,也会面临一些访问限制或者防护措施。这时候,使用HTTP代理爬虫可以有效地解决这些问题&#xff0…

普华永道踩坑MOVEit漏洞,泄露银行8万名储户的信息

8月14日,波多黎各自治区最大的银行——人民银行向缅因州司法部长提交了一份客户信息泄露报告。该报告指出,由于供应商普华永道使用的MOVEit软件存在安全漏洞,导致银行82217名储户的个人信息被泄露。 目前,波多黎各人民银行已经陆续…

javaScript:数组方法(增删/提取类/截取/操作方法等)

目录 一.数组的增删方法 1.push()数组末尾添加元素 解释 代码 运行截图 2.unshift()向数组的头部添加数组 解释 代码 运行截图 3.pop()数组的尾部删除一个元素 解释 代码 运行截图 4.shift()数组的头部删除一个元素 解释 代码 运行截图 5. splice()任意位…

使用 Visual Studio Code 调试 CMake 脚本

之前被引入到 Visual Studio 中的 CMake 调试器,现已在 Visual Studio Code 中可用。 也就是说,现在你可以通过在 VS Code 中安装 CMake 工具扩展,来调试你的 CMakeLists.txt 脚本了。是不是很棒? 背景知识 Visual C 开发团队和 CMake 的维…

最全的【DDD领域建模】小白学习手册(文末附资料)

1、前言: 在当时的环境下,单体应用仍然是市场的主体,但是大型复杂软件系统已经出现,给团队的设计和开发工作带来了比较大的挑战。 DDD提供了一种新的设计思路,通过对于业务子域和限界上下文的划分,建立跨…

【Oracle 数据库 SQL 语句 】积累1

Oracle 数据库 SQL 语句 1、分组之后再合计2、显示不为空的值 1、分组之后再合计 关键字: grouping sets ((分组字段1,分组字段2),()) select sylbdm ,count(sylbmc) a…

【数据结构OJ题】链表中倒数第k个结点

原题链接:https://www.nowcoder.com/practice/529d3ae5a407492994ad2a246518148a?tpId13&&tqId11167&rp2&ru/activity/oj&qru/ta/coding-interviews/question-ranking 目录 1. 题目描述 2. 思路分析 3. 代码实现 1. 题目描述 2. 思路分析 …

进程间通信——信号

信号的概念 信号是 Linux进程间通信的最古老的方式之一,是事件发生时对进程的通知机制,有时也称之为软件中断,它是在软件层次上对中断机制的一种模拟,是一种异步通信的方式。信号可以导致一个正在运行的进程被另一个正在运行的异…

手机商城网站的分析与设计(论文+源码)_kaic

目录 摘 要 1 1 绪论 2 1.1选题背景意义 2 1.2国内外研究现状 2 1.2.1国内研究现状 2 1.2.2国外研究现状 3 1.3研究内容 3 2 网上手机商城网站相关技术 4 2.1.NET框架 4 2.2Access数据库 4 2.3 JavaScript技术 4 3网上手机商城网站分析与设…

复古游戏库管理器RomM

什么是 RomM ? RomM(代表 Rom Manager)是一个专注于复古游戏的游戏库管理器。通过 Web 浏览器管理和组织您的所有游戏。受 Jellyfin 的启发,允许您从现代界面管理所有游戏,同时使用 IGDB 元数据丰富它们。 RomM 支持的…

线上通过Nginx部署前端工程,并且配置SSL

介绍、为了更好的帮助大家学习,减少歧义,IP地址我就不隐藏了,公司也是我自己的公司。你们就别来攻击了。 下面给出步骤: 一、前期准备工作 通过在目标服务器上安装宝塔面板、安装redis、mysql、nginx、jdk环境等 1、 2、前端工程通过npm run build 打…

完美解决Github提交PR后报错:File is not gofumpt-ed (gofumpt)

问题阐述 最近在Github上提交PR后,遇到了这么一个问题:golangci-lint运行失败,具体原因是File is not gofumpt-ed (gofumpt)。 名词解释 golangci-lint: golangci-lint 是Go语言社区中常用的代码质量检查工具,它可以…