当前位置: 首页>数据库>正文

mongodb for arm32架构 mongodb部署架构

MongoDB 是由C++语言编写的,是一个基于分布式文件存储的开源数据库系统。

在高负载的情况下,添加更多的节点,可以保证服务器性能。

MongoDB 旨在为WEB应用提供可扩展的高性能数据存储解决方案。

MongoDB 将数据存储为一个文档,数据结构由键值(key=>value)对组成。MongoDB 文档类似于 JSON 对象。字段值可以包含其他文档,数组及文档数组。

mongodb for arm32架构 mongodb部署架构,mongodb for arm32架构 mongodb部署架构_数据,第1张

主要特点

  • MongoDB 是一个面向文档存储的数据库,操作起来比较简单和容易。
  • 你可以在MongoDB记录中设置任何属性的索引 (如:FirstName=“Sameer”,Address=“8 Gandhi Road”)来实现更快的排序。
  • 你可以通过本地或者网络创建数据镜像,这使得MongoDB有更强的扩展性。
  • 如果负载的增加(需要更多的存储空间和更强的处理能力) ,它可以分布在计算机网络中的其他节点上这就是所谓的分片。
  • Mongo支持丰富的查询表达式。查询指令使用JSON形式的标记,可轻易查询文档中内嵌的对象及数组。
  • MongoDb 使用update()命令可以实现替换完成的文档(数据)或者一些指定的数据字段 。
  • Mongodb中的Map/reduce主要是用来对数据进行批量处理和聚合操作。
  • Map和Reduce。Map函数调用emit(key,value)遍历集合中所有的记录,将key与value传给Reduce函数进行处理。
  • Map函数和Reduce函数是使用Javascript编写的,并可以通过db.runCommand或mapreduce命令来执行MapReduce操作。
  • GridFS是MongoDB中的一个内置功能,可以用于存放大量小文件。
  • MongoDB允许在服务端执行脚本,可以用Javascript编写某个函数,直接在服务端执行,也可以把函数的定义存储在服务端,下次直接调用即可。
  • MongoDB支持各种编程语言:RUBY,PYTHON,JAVA,C++,PHP,C#等多种语言。
  • MongoDB安装简单。

windows安装

官网下载安装文件或者压缩包即可

安装有两种方式:

方式一:

在安装路径的bin同级目录下新建两级文件夹:data/db
然后进入bin目录打开命令窗口,输入命令
mongod --dbpath ..\data\db

方式二:

首先在bin同级目录下新建config文件夹中新建mongod.conf配置文件,编辑

storage:
    dbPath: D:\environment\MongoDB\data\db

然后到bin目录下打开命令窗口,输入以下命令行启动

mongod -f ..\config\mongod.conf

完成启动,发现mongodb的默认端口号是27017

开启了mongodb服务之后,该怎么连接呢,连接也有两种方式

方式一:

打开bin目录下的mongo.exe,直接输入以下命令就可以连接(甚至自动连接)

mongo

测试是否连接成功

> show dbs
admin   0.000GB
config  0.000GB
local   0.000GB

方式二:

可通过可视化工具来连接,需要下载compass,在官网下载解压即用,运行compass.exe文件,然后conect即可

mongodb for arm32架构 mongodb部署架构,mongodb for arm32架构 mongodb部署架构_数据_02,第2张

Linux安装

官网下载linux版本的mongodb

将压缩包放到linux系统中的usr/local/mongodb文件夹中,解压

cd /usr/local/mongodb
tar -xvf mongodb-linux-x86_64-4.0.10.tgz

新家几个目录,分别用来存储数据、日志和配置

mkdir -p /usr/local/mongodb/data
mkdir -p /usr/local/mongodb/log

在bin目录下新建并修改配置文件

vim /usr/local/mongodbmongodb-linux-x86_64-4.0.19/bin/mongod.conf

内容如下:

systemLog:
  #MongoDB发送所有日志输出的目标指定为文件
  destination: file
  path: "/usr/local/mongodb/log/mongod.log"
  # 当mongoos或mongod实例重新启动时,会将新条目附加到先有日志文件的末尾
  logAppend: true
storage:
  #mongod实例存储其数据的目录
  dbPath: "/usr/local/mongodb/data/db"
  journal:
    #启用或禁用持久性日志以确保数据文件保持有效和可恢复。 
    enabled: true
processManagement: 
   #启用在后台运行mongos或mongod进程的守护进程模式。 
   fork: true
net:
   #服务实例绑定的IP,默认是localhost 
   bindIp: localhost,172.16.0.17
   port: 27017

启动MongoDB服务

./mongod -f ./mongod.conf

启动成功

测试是否启动成功:

ps -ef|grep mongod

最后通过可视化界面来检测我们的mongodb,这时候不再是localhost了,而是要连接到我们的远程服务器上,需要填写远程服务器的主机名

连接成功

最后看下怎么关闭服务

方式一:

kill -2 进程id

方式二:

mongo --port 27017 
//#切换到admin库 
use admin 
//关闭服务 
db.shutdownServer()

数据库的创建和删除

存放文章评论的数据存放到MongoDB中,数据结构参考如下:

数据库:articledb

mongodb for arm32架构 mongodb部署架构,mongodb for arm32架构 mongodb部署架构_数据_03,第3张

选择和创建数据库

如果数据库不存在则自动创建

use articledb
查看数据库

查看有权限查看的所有的数据库命令

show dbs

注意:如果是空的db是不会显示出来的,例如刚刚创建的articledb,因为刚创建还没数据,也就是还没持久化到磁盘中,暂存在内存中

查看正在使用的数据库

db
删除数据库

MongoDB 删除数据库的语法格式如下:

db.dropDatabase()

提示:主要用来删除已经持久化的数据库

集合

创建集合

集合,类似关系型数据库中的表。 可以显示的创建,也可以隐式的创建

显式创建、查看、删除
> db.createCollection("my")
{ "ok" : 1 }
> show collections # 查看集合
my
> db.my.drop()
true
> show collections
>

集合的命名规范:

  • 集合名不能是空字符串""。
  • 集合名不能含有
  • 集合名不能以"system."开头,这是为系统集合保留的前缀。
  • 字符(空字符),这个字符表示集合名的结尾。
  • 用户创建的集合名字不能含有保留字符。有些驱动程序的确支持在集合名里面包含,这是因为某些系统生成的集合中包含该字符。除 非你要访问这种系统创建的集合,否则千万不要在名字里出现$。
  • 隐式创建

文档操作

当向一个集合中插入一个文档的时候,如果集合不存在,则会自动创建集合,通常我们使用隐式创建文档即可

插入文档

文档(document)的数据结构和 JSON 基本一样。 所有存储在集合中的数据都是 BSON 格式

单条插入

跟mysql一样既可以单条插入,也可以多条执行

db.collection.insert( <document or array of documents>, { writeConcern: <document>, ordered: <boolean> } )

使用insert() 或 save() 方法向集合中插入文档,语法如下:

> db.comment.insert({
...     "articleid": "100000",
...     "content": "今天天气真好,阳光明 媚",
...     "userid": "1001",
...     "nickname": "Rose",
...     "createdatetime": new Date(),
...     "likenum": NumberInt(10),
...     "state": null
... })
WriteResult({ "nInserted" : 1 }) # 表明插入成功
> show collections
comment
>

参数:

mongodb for arm32架构 mongodb部署架构,mongodb for arm32架构 mongodb部署架构_数据_04,第4张

示例:

要想comment的集合中插入一条测试数据(隐式插入)

  • comment集合如果不存在,则会隐式创建
  • 提示:

    • mongo中的数字,默认double类型,如要存整型,必须使用函数NumberInt,否则取出来就有问题了。
    • 插入当前日期使用 new Date()
    • 插入的数据没有指定 _id ,会自动生成主键值
    • 如果某字段没值,可以赋值为null,或不写该字段。
    • 文档中的键/值对是有序的。

    注意:

    1. 文档中的值不仅可以是在双引号里面的字符串,还可以是其他几种数据类型(甚至可以是整个嵌入的文档)。
    2. MongoDB区分类型和大小写。
    3. MongoDB的文档不能有重复的键。
    4. 文档的键是字符串。除了少数例外情况,键可以使用任意UTF-8字符。
    5. 键不能含有
    6. .和$有特别的意义,只有在特定环境下才能使用。
    7. (空字符)。这个字符用来表示键的结尾。

    文档键命名规范:

    • 以下划线"_"开头的键是保留的(不是严格要求的)
    • 批量插入
      db.collection.insertMany( [ <document 1> , <document 2>, ... ], { writeConcern: <document>, ordered: <boolean> } )
    > db.comment.insertMany([{ ... "_id": "1", ... "articleid": "100001", ... "content": "我们不应该把清晨浪费在手机上,健康很重要,一杯温水幸福你我 他。", ... "userid": "1002", ... "nickname": "相忘于江湖", ... "createdatetime": new Date("2019-08- 05T22:08:15.522Z"), ... "likenum": NumberInt(1000), ... "state": "1" ... }, ... { ... "_id": "2", ... "articleid": "100001", ... "content": "我夏天空腹喝凉开水,冬天喝温开水", ... "userid": "1005", ... "nickname": "伊人憔 悴", ... "createdatetime": new Date("2019-08-05T23:58:51.485Z"), ... "likenum": NumberInt(888), ... "state": "1" ... }, ... { ... "_id": "3", ... "articleid": "100001", ... "content": "我一直喝凉开水,冬天夏天都喝。", ... "userid": "1004", ... "nickname": "杰克船 长", ... "createdatetime": new Date("2019-08-06T01:05:06.321Z"), ... "likenum": NumberInt(666), ... "state": "1" ... }, ... { ... "_id": "4", ... "articleid": "100001", ... "content": "专家说不能空腹吃饭,影响健康。", ... "userid": "1003", ... "nickname": "凯 撒", ... "createdatetime": new Date("2019-08-06T08:18:35.288Z"), ... "likenum": NumberInt(2000), ... "state": "1" ... }, ... { ... "_id": "5", ... "articleid": "100001", ... "content": "研究表明,刚烧开的水千万不能喝,因为烫 嘴。", ... "userid": "1003", ... "nickname": "凯撒", ... "createdatetime": new Date("2019-08- 06T11:01:02.521Z"), ... "likenum": NumberInt(3000), ... "state": "1" ... }]); { "acknowledged" : true, "insertedIds" : [ "1", "2", "3", "4", "5" ] }

    语法:

    try {  
        db.comment.insertMany([{
        "_id": "1",
        "articleid": "100001",
        "content": "我们不应该把清晨浪费在手机上,健康很重要",
        "userid": "1002",
        "nickname": "相忘于江湖",
        "createdatetime": new Date("2019-08- 05T22:08:15.522Z"),
        "likenum": NumberInt(1000),
        "state": "1"
        },
        {
            "_id": "2",
            "articleid": "100001",
            "content": "我夏天空腹喝凉开水,冬天喝温开水",
            "userid": "1005",
            "nickname": "伊人憔 悴",
            "createdatetime": new Date("2019-08-05T23:58:51.485Z"),
            "likenum": NumberInt(888),
            "state": "1"
        },
        {
            "_id": "3",
            "articleid": "100001",
            "content": "我一直喝凉开水,冬天夏天都喝。",
            "userid": "1004",
            "nickname": "杰克船 长",
            "createdatetime": new Date("2019-08-06T01:05:06.321Z"),
            "likenum": NumberInt(666),
            "state": "1"
        },
        {
            "_id": "4",
            "articleid": "100001",
            "content": "专家说不能空腹吃饭,影响健康。",
            "userid": "1003",
            "nickname": "凯 撒",
            "createdatetime": new Date("2019-08-06T08:18:35.288Z"),
            "likenum": NumberInt(2000),
            "state": "1"
        },
        {
            "_id": "5",
            "articleid": "100001",
            "content": "研究表明,刚烧开的水千万不能喝,因为烫 嘴。",
            "userid": "1003",
            "nickname": "凯撒",
            "createdatetime": new Date("2019-08- 06T11:01:02.521Z"),
            "likenum": NumberInt(3000),
            "state": "1"
        }]);
    } catch (e) { 
        print (e); 
    }

    示例:

    查询文档

    提示:

    插入时指定了 _id ,则主键就是该值。

    如果某条数据插入失败,将会终止插入,但已经插入成功的数据不会回滚掉。

    因为批量插入由于数据较多容易出现失败,因此,可以使用try catch进行异常捕捉处理,测试的时候可以不处理。

    db.collection.find(<query>, [projection])
    Parameter

    查询数据的语法格式如下:

    Type

    参数:

    Description

    查询所有

    db.comment.find() # 或 db.comment.find({})

    query

    document

    可选。使用查询运算符指定选择筛选器。若要返回集合中的所有文档,请省略此参数或传递空文档 ({})

    projection

    document

    可选。指定要在与查询筛选器匹配的文档中返回的字段(投影)。若要返回匹配文档中的所有字段,

    示例:

    > db.comment.find({userid:"1003"}) { "_id" : "4", "articleid" : "100001", "content" : "专家说不能空腹吃饭,影响健康。", "userid" : "1003", "nickname" : "凯 撒", "createdatetime" : ISODate("2019-08-06T08:18:35.288Z"), "likenum" : 2000, "state" : "1" } { "_id" : "5", "articleid" : "100001", "content" : "研究表明,刚烧开的水千万不能喝,因为烫 嘴。", "userid" : "1003", "nickname" : "凯撒", "createdatetime" : ISODate("1970-01-01T00:00:00Z"), "likenum" : 3000, "state" : "1" }

    如果我们要查询集合的所有文档,我们输入以下命令

    查询单条

    这里你会发现每条文档会有一个叫_id的字段,这个相当于我们原来关系数据库中表的主键,当你在插入文档记录时没有指定该字段, MongoDB会自动创建,其类型是ObjectID类型。 如果我们在插入文档记录时指定该字段也可以,其类型可以是ObjectID类型,也可以是MongoDB支持的任意类型.

    如果我想按一定条件来查询,比如我想查询userid为1003的记录,怎么办?很简单!只 要在fifind()中添加参数即可,参数也是json格式,如 下:

    > db.comment.findOne({userid:"1003"})
    {
            "_id" : "4",
            "articleid" : "100001",
            "content" : "专家说不能空腹吃饭,影响健康。",
            "userid" : "1003",
            "nickname" : "凯 撒",
            "createdatetime" : ISODate("2019-08-06T08:18:35.288Z"),
            "likenum" : 2000,
            "state" : "1"
    }
    >
    投影查询

    如果你只需要返回符合条件的第一条数据,我们可以使用fifindOne命令来实现,语法和fifind一样。

    如:查询用户编号是1003的记录,但只最多返回符合条件的第一条记录:

    > db.comment.find({userid:"1003"},{userid:1,nickname:1})
    { "_id" : "4", "userid" : "1003", "nickname" : "凯 撒" }
    { "_id" : "5", "userid" : "1003", "nickname" : "凯撒" }
    > db.comment.find({userid:"1003"},{userid:1,nickname:1,_id:0}) { "userid" : "1003", "nickname" : "凯 撒" } { "userid" : "1003", "nickname" : "凯撒" }

    如果要查询结果返回部分字段,则需要使用投影查询(不显示所有字段,只显示指定的字段)。

    如:查询结果只显示 _id、userid、nickname :

    db.comment.find({},{userid:1,nickname:1})

    如:查询结果只显示 、userid、nickname ,不显示 _id :

    统计查询

    再例如:查询所有数据,但只显示 _id、userid、nickname :

    db.collection.count(query, options)
    Parameter

    语法:

    Type

    参数:

    Description

    > db.comment.count() 6 > db.comment.count({userid:"1003"}) 2 >

    分页查询

    query

    document

    查询选择条件。

    options

    document

    可选。用于修改计数的额外选项。

    示例:

    统计comment集合的所有的记录数

    db.COLLECTION_NAME.find().limit(NUMBER).skip(NUMBER)
    > db.comment.find().limit(3) { "_id" : ObjectId("5eee1393b9ba7b116ffa7823"), "articleid" : "100000", "content" : "今天天气真好,阳光明 媚", "userid" : "1001", "nickname" : "Rose", "createdatetime" : ISODate("2020-06-20T13:48:03.665Z"), "likenum" : 10, "state" : null } { "_id" : "1", "articleid" : "100001", "content" : "我们不应该把清晨浪费在手机上,健康很重要,一杯温水幸福你我 他。", "userid" : "1002", "nickname" : "相忘于江湖", "createdatetime" : ISODate("1970-01-01T00:00:00Z"), "likenum" : 1000, "state" : "1" } { "_id" : "2", "articleid" : "100001", "content" : "我夏天空腹喝凉开水,冬天喝温开水", "userid" : "1005", "nickname" : "伊人憔 悴", "createdatetime" : ISODate("2019-08-05T23:58:51.485Z"), "likenum" : 888, "state" : "1" } >

    可以使用limit()方法来读取指定数量的数据,使用skip()方法来跳过指定数量的数据

    基本语法如下所示:

    > db.comment.find().skip(3)
    { "_id" : "3", "articleid" : "100001", "content" : "我一直喝凉开水,冬天夏天都喝。", "userid" : "1004", "nickname" : "杰克船 长", "createdatetime" : ISODate("2019-08-06T01:05:06.321Z"), "likenum" : 666, "state" : "1" }
    { "_id" : "4", "articleid" : "100001", "content" : "专家说不能空腹吃饭,影响健康。", "userid" : "1003", "nickname" : "凯 撒", "createdatetime" : ISODate("2019-08-06T08:18:35.288Z"), "likenum" : 2000, "state" : "1" }
    { "_id" : "5", "articleid" : "100001", "content" : "研究表明,刚烧开的水千万不能喝,因为烫 嘴。", "userid" : "1003", "nickname" : "凯撒", "createdatetime" : ISODate("1970-01-01T00:00:00Z"), "likenum" : 3000, "state" : "1" }

    如果你想返回指定条数的记录,可以在fifind方法后调用limit来返回结果(TopN),默认值20,例如

    排序查询

    skip方法同样接受一个数字参数作为跳过的记录条数。(前N个不要),默认值是0

    db.COLLECTION_NAME.find().sort({KEY:1})
    > db.comment.find().sort({userid:-1,likenum:1}) { "_id" : "2", "articleid" : "100001", "content" : "我夏天空腹喝凉开水,冬天喝温开水", "userid" : "1005", "nickname" : "伊人憔 悴", "createdatetime" : ISODate("2019-08-05T23:58:51.485Z"), "likenum" : 888, "state" : "1" } { "_id" : "3", "articleid" : "100001", "content" : "我一直喝凉开水,冬天夏天都喝。", "userid" : "1004", "nickname" : "杰克船 长", "createdatetime" : ISODate("2019-08-06T01:05:06.321Z"), "likenum" : 666, "state" : "1" } { "_id" : "4", "articleid" : "100001", "content" : "专家说不能空腹吃饭,影响健康。", "userid" : "1003", "nickname" : "凯 撒", "createdatetime" : ISODate("2019-08-06T08:18:35.288Z"), "likenum" : 2000, "state" : "1" } { "_id" : "5", "articleid" : "100001", "content" : "研究表明,刚烧开的水千万不能喝,因为烫 嘴。", "userid" : "1003", "nickname" : "凯撒", "createdatetime" : ISODate("1970-01-01T00:00:00Z"), "likenum" : 3000, "state" : "1" } { "_id" : "1", "articleid" : "100001", "content" : "我们不应该把清晨浪费在手机上,健康很重要,一杯温水幸福你我 他。", "userid" : "1002", "nickname" : "相忘于江湖", "createdatetime" : ISODate("1970-01-01T00:00:00Z"), "likenum" : 1000, "state" : "1" } { "_id" : ObjectId("5eee1393b9ba7b116ffa7823"), "articleid" : "100000", "content" : "今天天气真好,阳光明 媚", "userid" : "1001", "nickname" : "Rose", "createdatetime" : ISODate("2020-06-20T13:48:03.665Z"), "likenum" : 10, "state" : null } >

    sort() 方法对数据进行排序,sort() 方法可以通过参数指定排序的字段,并使用 1 和 -1 来指定排序的方式,其中 1 为升序排列,而 -1 是用 于降序排列

    正则查询

    例如:

    对userid降序排列,并对访问量进行升序排列

    正则表达式

    提示:

    skip(), limilt(), sort()三个放在一起执行的时候,执行的顺序是先 sort(), 然后是 skip(),最后是显示的 limit(),和命令编写顺序无关。

    db.collection.find({field:/正则表达式/})

    MongoDB的模糊查询是通过> db.comment.find({content:/空腹/}) { "_id" : "2", "articleid" : "100001", "content" : "我夏天空腹喝凉开水,冬天喝温开水", "userid" : "1005", "nickname" : "伊人憔 悴", "createdatetime" : ISODate("2019-08-05T23:58:51.485Z"), "likenum" : 888, "state" : "1" } { "_id" : "4", "articleid" : "100001", "content" : "专家说不能空腹吃饭,影响健康。", "userid" : "1003", "nickname" : "凯 撒", "createdatetime" : ISODate("2019-08-06T08:18:35.288Z"), "likenum" : 2000, "state" : "1" } > db.comment.find({content:/^我们/}) { "_id" : "1", "articleid" : "100001", "content" : "我们不应该把清晨浪费在手机上,健康很重要,一杯温水幸福你我 他。", "userid" : "1002", "nickname" : "相忘于江湖", "createdatetime" : ISODate("1970-01-01T00:00:00Z"), "likenum" : 1000, "state" : "1" } >的方式实现的。格式为:

    比较查询

    提示:正则表达式是js的语法,直接量的写法。

    例如,我要查询评论内容包含“开水”的所有文档,代码如下:

    db.集合名称.find({ "field" : { $gt: value }}) // 大于: field > value 
    db.集合名称.find({ "field" : { $lt: value }}) // 小于: field < value 
    db.集合名称.find({ "field" : { $gte: value }}) // 大于等于: field >= value 
    db.集合名称.find({ "field" : { $lte: value }}) // 小于等于: field <= value 
    db.集合名称.find({ "field" : { $ne: value }}) // 不等于: field != value
    > db.comment.find({likenum:{$gt:NumberInt(700)}}) { "_id" : "1", "articleid" : "100001", "content" : "我们不应该把清晨浪费在手机上,健康很重要,一杯温水幸福你我 他。", "userid" : "1002", "nickname" : "相忘于江湖", "createdatetime" : ISODate("1970-01-01T00:00:00Z"), "likenum" : 1000, "state" : "1" } { "_id" : "2", "articleid" : "100001", "content" : "我夏天空腹喝凉开水,冬天喝温开水", "userid" : "1005", "nickname" : "伊人憔 悴", "createdatetime" : ISODate("2019-08-05T23:58:51.485Z"), "likenum" : 888, "state" : "1" } { "_id" : "4", "articleid" : "100001", "content" : "专家说不能空腹吃饭,影响健康。", "userid" : "1003", "nickname" : "凯 撒", "createdatetime" : ISODate("2019-08-06T08:18:35.288Z"), "likenum" : 2000, "state" : "1" } { "_id" : "5", "articleid" : "100001", "content" : "研究表明,刚烧开的水千万不能喝,因为烫 嘴。", "userid" : "1003", "nickname" : "凯撒", "createdatetime" : ISODate("1970-01-01T00:00:00Z"), "likenum" : 3000, "state" : "1" } >

    <, <=, >, >= 这个操作符也是很常用的,格式如下:

    包含查询

    示例:查询评论点赞数量大于700的记录

    > db.comment.find({userid:{$in:["1003","1004"]}})
    { "_id" : "3", "articleid" : "100001", "content" : "我一直喝凉开水,冬天夏天都喝。", "userid" : "1004", "nickname" : "杰克船 长", "createdatetime" : ISODate("2019-08-06T01:05:06.321Z"), "likenum" : 666, "state" : "1" }
    { "_id" : "4", "articleid" : "100001", "content" : "专家说不能空腹吃饭,影响健康。", "userid" : "1003", "nickname" : "凯 撒", "createdatetime" : ISODate("2019-08-06T08:18:35.288Z"), "likenum" : 2000, "state" : "1" }
    { "_id" : "5", "articleid" : "100001", "content" : "研究表明,刚烧开的水千万不能喝,因为烫 嘴。", "userid" : "1003", "nickname" : "凯撒", "createdatetime" : ISODate("1970-01-01T00:00:00Z"), "likenum" : 3000, "state" : "1" }
    >
    条件连接查询

    包含使用$in操作符。 示例:查询评论的集合中userid字段包含1003或1004的文档

    $and:[ { },{ },{ } ]
    > db.comment.find({$and:[{likenum:{$gte:NumberInt(700)}},{likenum:{$lt:NumberInt(2000)}}]}) { "_id" : "1", "articleid" : "100001", "content" : "我们不应该把清晨浪费在手机上,健康很重要,一杯温水幸福你我 他。", "userid" : "1002", "nickname" : "相忘于江湖", "createdatetime" : ISODate("1970-01-01T00:00:00Z"), "likenum" : 1000, "state" : "1" } { "_id" : "2", "articleid" : "100001", "content" : "我夏天空腹喝凉开水,冬天喝温开水", "userid" : "1005", "nickname" : "伊人憔 悴", "createdatetime" : ISODate("2019-08-05T23:58:51.485Z"), "likenum" : 888, "state" : "1" } >

    我们如果需要查询同时满足两个以上条件,需要使用$and操作符将条件进行关联。 格式为:

    $or:[ { },{ },{ } ]

    示例:查询评论集合中likenum大于等于700 并且小于2000的文档:

    修改文档

    如果两个以上条件之间是或者的关系,我们使用 操作符进行关联,与前面 and的使用方式相同 格式为:

    db.collection.update(query, update, options) 
    或 
    db.collection.update( 
        <query>, 
        <update>, 
        { 
            upsert: <boolean>, 
            multi: <boolean>, 
            writeConcern: <document>, 
            collation: <document>, 
            arrayFilters: [ <filterdocument1>, ... ], 
            hint: <document|string> // Available starting in MongoDB 4.2 
        }
    )
    覆盖修改
    > db.comment.update({_id:"1"},{likenum:NumberInt(1001)})
    WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
    > db.comment.findOne({_id:"1"})
    { "_id" : "1", "likenum" : 1001 }
    >
    局部修改

    如果我们想修改_id为1的记录,点赞量为1001,输入以下语句:

    > db.comment.update({_id:"2"},{$set:{likenum:NumberInt(889)}})
    WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
    > db.comment.findOne({_id:"2"})
    {
            "_id" : "2",
            "articleid" : "100001",
            "content" : "我夏天空腹喝凉开水,冬天喝温开水",
            "userid" : "1005",
            "nickname" : "伊人憔 悴",
            "createdatetime" : ISODate("2019-08-05T23:58:51.485Z"),
            "likenum" : 889,
            "state" : "1"
    }
    >

    执行后,我们会发现,这条文档除了likenum字段其它字段都不见了

    批量修改

    为了解决这个问题,我们需要使用修改器$set来实现,命令如下:

    我们想修改_id为2的记录,浏览量为889,输入以下语句:

    > db.comment.update({userid:"1003"},{$set:{nickname:"凯撒2"}})
    WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
    > db.comment.find({userid:"1003"})
    { "_id" : "4", "articleid" : "100001", "content" : "专家说不能空腹吃饭,影响健康。", "userid" : "1003", "nickname" : "凯撒2", "createdatetime" : ISODate("2019-08-06T08:18:35.288Z"), "likenum" : 2000, "state" : "1" }
    { "_id" : "5", "articleid" : "100001", "content" : "研究表明,刚烧开的水千万不能喝,因为烫 嘴。", "userid" : "1003", "nickname" : "凯撒", "createdatetime" : ISODate("1970-01-01T00:00:00Z"), "likenum" : 3000, "state" : "1" }
    > db.comment.update({userid:"1003"},{$set:{nickname:"凯撒大帝"}},{multi:true})
    WriteResult({ "nMatched" : 2, "nUpserted" : 0, "nModified" : 2 })
    >  db.comment.find({userid:"1003"})
    { "_id" : "4", "articleid" : "100001", "content" : "专家说不能空腹吃饭,影响健康。", "userid" : "1003", "nickname" : "凯撒大帝", "createdatetime" : ISODate("2019-08-06T08:18:35.288Z"), "likenum" : 2000, "state" : "1" }
    { "_id" : "5", "articleid" : "100001", "content" : "研究表明,刚烧开的水千万不能喝,因为烫 嘴。", "userid" : "1003", "nickname" : "凯撒大帝", "createdatetime" : ISODate("1970-01-01T00:00:00Z"), "likenum" : 3000, "state" : "1" }
    >
    列值增长的修改

    更新所有用户为 1003 的用户的昵称为 凯撒大帝 。

    > db.comment.update({_id:"3"},{$inc:{likenum:Number(1)}})
    WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
    >

    提示:如果不加后面的参数,则只更新符合条件的第一条记录

    删除文档

    如果我们想实现对某列值在原有值的基础上进行增加或减少,可以使用 $inc 运算符来实现。

    需求:对3号数据的点赞数,每次递增1

    db.集合名称.remove(条件)
    db.comment.remove({})

    删除文档的语法结构:

    > db.comment.remove({_id:"1"})
    WriteResult({ "nRemoved" : 1 })
    >

    以下语句可以将数据全部删除,请慎用

    常用命令小结

    如果删除_id=1的记录,输入以下语句

    use articledb
    db.comment.insert({bson数据})

    选择切换数据库:

    db.comment.find()

    插入数据:

    db.comment.find({条件})

    查询所有数据:

    db.comment.findOne({条件})

    条件查询数据:

    db.comment.find({条件}).limit(条数)

    查询符合条件的第一条记录:

    db.comment.find({条件}).skip(条数)

    查询符合条件的前几条记录:

    db.comment.update({条件},{修改后的数据}) 
    或
    db.comment.update({条件},{$set:{要修改部分的字段:数据})

    查询符合条件的跳过的记录:

    db.comment.update({条件},{$inc:{自增的字段:步进值}})

    修改数据:

    db.comment.remove({条件})

    修改数据并自增某字段值:

    db.comment.count({条件})

    删除数据:

    db.comment.find({字段名:/正则表达式/})

    统计查询:

    db.comment.find({字段名:{$gt:值}})

    模糊查询:

    db.comment.find({字段名:{$in:[值1,值2]}})
    或
    db.comment.find({字段名:{$nin:[值1,值2]}})

    条件比较运算:

    db.comment.find({$and:[{条件1},{条件2}]})
    或
    db.comment.find({$or:[{条件1},{条件2}]})

    包含查询:

    索引

    条件连接查询:

    索引的类型
    单字段索引

    索引支持在MongoDB中高效地执行查询。如果没有索引,MongoDB必须执行全集合扫描,即扫描集合中的每个文档,以选择与查询语句匹配的文档。这种扫描全集合的查询效率是非常低的,特别在处理大量的数据时,查询可以要花费几十秒甚至几分钟,这对网站的性能是非常致命的。

    如果查询存在适当的索引,MongoDB可以使用该索引限制必须检查的文档数。

    索引是特殊的数据结构,它以易于遍历的形式存储集合数据集的一小部分。索引存储特定字段或一组字段的值,按字段值排序。索引项的排序支持有效的相等匹配和基于范围的查询操作。此外,MongoDB还可以使用索引中的排序返回排序结果。

    官网文档:https://docs.mongodb.com/manual/indexes/

    MongoDB索引使用B树数据结构(确切的说是B-Tree,MySQL是B+Tree)

    复合索引
    其他索引

    MongoDB支持在文档的单个字段上创建用户定义的升序/降序索引,称为单字段索引(Single Field Index)。

    对于单个字段索引和排序操作,索引键的排序顺序(即升序或降序)并不重要,因为MongoDB可以在任何方向上遍历索引。

    地理空间索引

    MongoDB还支持多个字段的用户定义索引,即复合索引(Compound Index)。

    复合索引中列出的字段顺序具有重要意义。例如,如果复合索引由 { userid: 1, score: -1 } 组成,则索引首先按userid正序排序,然后在每个userid的值内,再在按score倒序排序

    文本索引

    地理空间索引(Geospatial Index)、文本索引(Text Indexes)、哈希索引(Hashed Indexes)。

    哈希索引

    为了支持对地理空间坐标数据的有效查询,MongoDB提供了两种特殊的索引:返回结果时使用平面几何的二维索引和返回结果时使用球面 几何的二维球面索引。

    索引管理

    MongoDB提供了一种文本索引类型,支持在集合中搜索字符串内容。这些文本索引不存储特定于语言的停止词(例如“the”、“a”、“or”),而将集合中的词作为词干,只存储根词。

    查询索引

    为了支持基于散列的分片,MongoDB提供了散列索引类型,它对字段值的散列进行索引。这些索引在其范围内的值分布更加随机,但只支 持相等匹配,不支持基于范围的查询。

    > db.comment.getIndexes() [ { "v" : 2, # 索引引擎版本 "key" : { "_id" : 1 # 索引对应的字段:1代表升序 }, "name" : "_id_", # 索引名称 "ns" : "test.comment" } ] >id

    返回一个集合中的所有索引的数组

    创建索引

    结果中显示的是默认 _id 索引。

    默认_id索引:

    MongoDB在创建集合的过程中,在 _id 字段上创建一个唯一的索引,默认名字为 db.collection.createIndex(keys, options) ,该索引可防止客户端插入两个具有相同值的文 档,您不能在_id字段上删除此索引。

    注意:该索引是唯一索引,因此值不能重复,即 _id 值不能重复的。在分片集群中,通常使用 _id 作为片键

    db.collection.createIndex(keys, options)

    在集合上创建索引。

    db.comment.createIndex({userid:1}) 
    { 
    	"createdCollectionAutomatically" : false, 
    	"numIndexesBefore" : 1, 
    	"numIndexesAfter" : 2, 
    	"ok" : 1 
    }

    在集合上创建索引。

    db.comment.createIndex({userid:1,nickname:-1}) 
    { 
    	"createdCollectionAutomatically" : false, 
    	"numIndexesBefore" : 2, 
    	"numIndexesAfter" : 3, 
    	"ok" : 1 
    }

    参数:

    mongodb for arm32架构 mongodb部署架构,mongodb for arm32架构 mongodb部署架构_数据_05,第5张

    options(更多选项)列表:

    mongodb for arm32架构 mongodb部署架构,mongodb for arm32架构 mongodb部署架构_数据_06,第6张

    提示:

    注意在 3.0.0 版本前创建索引方法为 db.collection.ensureIndex() ,之后的版本使用了 db.collection.createIndex() 方法, ensureIndex() 还能用,但只是createIndex() 的别名。

    【示例】

    (1)单字段索引示例:对 userid 字段建立索引:

    索引的移除

    (2)复合索引:对 userid 和 nickname 同时建立复合(Compound)索引:

    db.collection.dropIndex(index)
    db.collection.dropIndexes()

    可以移除指定的索引,或移除所有索引

    移除指定索引:

    索引的使用

    移除所有索引:

    注意:_id的索引是不会被删除的

    执行计划
    db.collection.find(query,options).explain(options)> db.comment.find({userid:"1003"}).explain() { "queryPlanner" : { "plannerVersion" : 1, "namespace" : "test.comment", "indexFilterSet" : false, "parsedQuery" : { "userid" : { "$eq" : "1003" } }, "winningPlan" : { "stage" : "COLLSCAN", "filter" : { "userid" : { "$eq" : "1003" } }, "direction" : "forward" }, "rejectedPlans" : [ ] }, "serverInfo" : { "host" : "ryan", "port" : 27017, "version" : "4.0.19", "gitVersion" : "7e28f4296a04d858a2e3dd84a1e79c9ba59a9568" }, "ok" : 1 }

    分析查询性能(Analyze Query Performance)通常使用执行计划(解释计划、Explain Plan)来查看查询的情况,如查询耗费的时间、是否基于索引查询等。

    那么,通常,我们想知道,建立的索引是否有效,效果如何,都需要通过执行计划查看

    > db.comment.createIndex({userid:1})
    {
            "createdCollectionAutomatically" : false,
            "numIndexesBefore" : 1,
            "numIndexesAfter" : 2,
            "ok" : 1
    }

    示例:

    查看根据userid查询数据的情况:

    涵盖的查询

    关键点看: “stage” : “COLLSCAN”, 表示全集合扫描,也就是全部5条数据都要查一遍,再选择符合条件的,这个查询方式就比较低了

    mongodb for arm32架构 mongodb部署架构,mongodb for arm32架构 mongodb部署架构_mongodb for arm32架构_07,第7张

    我们尝试给userid加上索引,再查一下看看

    springboot整合MongoDB

    mongodb for arm32架构 mongodb部署架构,mongodb for arm32架构 mongodb部署架构_mongodb_08,第8张

    再次查看执行计划,关键点看: “stage” : “IXSCAN” ,基于索引的扫描,然后抓取fetch

    这时候会先去索引库中扫描数据,再抓取符合条件的数据,总共才查了2条数据,对比没有索引的,效率肯定是提高了,如果是大数据,就会非常明显

    1、创建项目,导入依赖

    当查询条件和查询的投影仅包含索引字段时,MongoDB直接从索引返回结果,而不扫描任何文档或将文档带入内存,这些覆盖的查询非常高效

    mongodb for arm32架构 mongodb部署架构,mongodb for arm32架构 mongodb部署架构_数据_09,第9张

    示例:

    mongodb for arm32架构 mongodb部署架构,mongodb for arm32架构 mongodb部署架构_字段_10,第10张

    <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.3.1.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.ryan</groupId> <artifactId>mongodb-study</artifactId> <version>1.0-SNAPSHOT</version> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>8</source> <target>8</target> </configuration> </plugin> </plugins> </build> <dependencies> <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.12</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-data-mongodb --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-mongodb</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions> </dependency> <dependency> <!-- this is needed or IntelliJ gives junit.jar or junit-platform-launcher:1.3.2 not found errors --> <groupId>org.junit.platform</groupId> <artifactId>junit-platform-launcher</artifactId> <scope>test</scope> </dependency> </dependencies> </project>

    主要结合springboot-mangodb对数据的操作

    表结构分析

    mongodb for arm32架构 mongodb部署架构,mongodb for arm32架构 mongodb部署架构_字段_11,第11张

    技术选型

    SpringDataMongoDB

    实战:

    2、配置yml文件

    spring:
      # 数据源配置
      data:
        mongodb:
          # 主机地址
          host: 203.195.160.231
          # 数据库
          database: test
          # 默认端口号:27017
          port: 27017

    3、编写主启动类

    @SpringBootApplication
    public class ArticleApplication {
         public static void main(String[] args) {
               SpringApplication.run(ArticleApplication.class, args);
          }
    }

    4、编写实体类

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    @Document(collection = "comment")//指定对应的集合
    @CompoundIndex(def = "{'userid':1, 'nickname':-1}")//也可以在类上添加索引
    @Accessors(chain = true)//支持链式编程
    public class Comment implements Serializable {
    
        //@Id
        private String id;//主键,_id,如果属性名时id,可以省略注解@Id
        @Field("content")
        private String content;//如果属性名称和集合中的字段名字不一样,可以像这样添加注解
        private Date publishtime;
        @Indexed
        private String userid;//添加索引,一般会通过命令行去添加索引
        private String nickname;
        private LocalDateTime createdatetime;
        private Integer likenum;
        private Integer replynum;
        private String parentid;
        private String articleid;
    }

    5、编写dao层

    注意:由于是非关系型数据库,所以实体类属性和mongodb数据库中已经存在的字段不需要不一定要保持一致

    //评论的持久层接口
    public interface CommentDao extends MongoRepository<Comment, String> {
        
        //继承MongoRepository之后已经继承了很多crud方法,具体可以点进去查看
    
        //如果想要实现分页查询,我们需要另增方法,注意方法名格式是有要求的,findBy+字段名
        Page<Comment> findByUserid(String userid, Pageable pageable);
    
    }

    6、编写service层

    @Service
    public class CommentService {
    
        @Autowired
        private CommentDao commentDao;
    
        @Autowired
        private MongoTemplate mongoTemplate;
    
        //调用dao的方法,都是通过dao继承MongoRepository过来的
        //增
        public void saveComment(Comment comment){
            commentDao.save(comment);
        }
    
        //更新
        public void updateComment(Comment comment){
            commentDao.save(comment);
        }
    
        //根据id删除
        public void deleteCommentById(String id){
            commentDao.deleteById(id);
        }
    
        //删除所有
        public void deleteAllComments(){
            commentDao.deleteAll();
        }
    
        //根据id查询
        public Comment findById(String id){
            return commentDao.findById(id).get();
        }
    
        //查询所有
        public List<Comment> findAll(){
            return commentDao.findAll();
        }
    
        //分页查询
        public Page<Comment> findByPage(String userid, int pageNo, int pageSize){
            return commentDao.findByUserid(userid, PageRequest.of(pageNo,pageSize));
        }
    
        //实现点赞+1
        public void updateCommentLikenum(String id){
            //查询条件
            Query query = Query.query(Criteria.where("_id").is(id));//查询的条件,如果是多个条件,可以在后面addCriteria
            //更新条件
            Update update = new Update();
            update.inc("likenum");//自增1
            //执行更新
            mongoTemplate.updateFirst(query, update, Comment.class);
        }
    
    }
    @SpringBootTest public class ArticleApplicationTests { @Resource private CommentService commentService; @Test void test1(){ Comment comment = new Comment(); comment.setContent("ryan自学java") .setPublishtime(new Date()) .setUserid("10086") .setNickname("牛排") .setCreatedatetime(LocalDateTime.now()) .setLikenum(999) .setReplynum(40) .setArticleid("9527"); commentService.saveComment(comment); } //其他的crud方法就不一一测试了 //如果想要实现分页查询,可以通过在dao层自定义一个方法查询 //另外如果想通过mongodb实现点赞数+1的话,原生的+1方法效率比较低,这时候我们可以通过MongoTemplate来实现 @Test void testAddLikenum(){ commentService.updateCommentLikenum("2"); } }
  • 测试前,别忘了开mongodb的服务哦,我这里是将mongodb部署到远程服务上的
  • 7、测试

  • 另外可以结合可视化工具compass方便查看数据哦
  • 注意:

      以上是mongodb的简单入门,先写到这里,后续会再进一步学习mongodb

      如果需要获取相关资料的也可以私信我哦,觉得可以帮助到你的话麻烦帮忙点个赞



      https://www.xamrdz.com/database/6df1963431.html

      相关文章: