“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 } )
相关推荐
pp-周子晗(努力赶上课程进度版)5 分钟前
【MYSQL】基本查询,表的增删查改
数据库·mysql
英英_27 分钟前
详细介绍一下Python连接MySQL数据库的完整步骤
数据库·python·mysql
IvanCodes1 小时前
十一、Hive JOIN 连接查询
大数据·hive
LabVIEW开发1 小时前
LabVIEW数据库使用说明
数据库·sql·labview知识
Python智慧行囊2 小时前
Python Django 的 ORM 编程思想及使用步骤
数据库·python·django·orm
南方以南_2 小时前
【云实验】Excel文件转存到RDS数据库
数据库·excel
Listennnn4 小时前
Neo4j数据库
数据库·人工智能·neo4j
小飞敲代码4 小时前
【Hadoop 实战】Yarn 模式上传 HDFS 卡顿时 “No Route to Host“ 错误深度解析与解决方案
大数据·linux·运维·服务器·hadoop·分布式·hdfs
Liu1bo4 小时前
【MySQL】库与表的操作
数据库·mysql·oracle
冬瓜的编程笔记4 小时前
【MySQL成神之路】MySQL常用语法总结
数据库·mysql