目录

前言 1.1

简介 1.2

安装 1.3

Mac中安装MongoDB 1.3.1

基本用法 1.4

Server端 1.4.1

Client端 1.4.2

命令行shell 1.4.2.1

GUI工具 1.4.2.2

MongoDB Compass 1.4.2.2.1

API 1.4.2.3

PyMongo 1.4.2.3.1

高级用法 1.5

IP限制 1.5.1

用户和权限 1.5.2

心得和总结 1.6

PyMongo心得 1.6.1

生成URI 1.6.1.1

插入新增记录 1.6.1.2

设置时间范围等查询条件 1.6.1.3

备份和恢复 1.6.2

mongodump和mongorestore 1.6.2.1

mongoexport和mongoimport 1.6.2.2

新建空数据库和集合 1.6.3

如何更新数据 1.6.4

高级搜索 1.6.5

GridFS存储文件 1.6.6

查看当前MongoDB信息 1.6.7

连接远程MongoDB的方式 1.6.8

坑 1.7

停止MongoDB 1.7.1

Cursor not found 1.7.2

参数_id是不是字符串 1.7.3

不要在admin中创建普通用户 1.7.4

附录 1.8

教程和文档 1.8.1

参考资料 1.8.2

前言

主流文档型数据库：MongoDB

最新版本：v1.3

更新时间：20200910

简介

介绍主流文档型关系数据库MongoDB的起源；如何安装；基本的使用方法，包括如何启动服务端和如何用shell、GUI图形界面工具、代码调用API接口等方式去Client端的使用；以及部分高级用法，包括IP限制、用户和权限等；总结各种心得，包括pymongo的各种方面，备份和回复，如何新建空数据库和集合，如何更新已有数据，如何进行正则、列表、嵌套等高级搜索查询，如何使用GridFS保存二进制文件，以及一些常用教程和文档；总结出常见的各种坑及解决办法。

源码+浏览+下载

本书的各种源码、在线浏览地址、多种格式文件下载如下：

Gitbook源码

crifan/popular_document_db_mongodb: 主流文档型数据库：MongoDB

如何使用此Gitbook源码去生成发布为电子书

详见：crifan/gitbook_template: demo how to use crifan gitbook template and demo

在线浏览

主流文档型数据库：MongoDB book.crifan.com

主流文档型数据库：MongoDB crifan.github.io

离线下载阅读

主流文档型数据库：MongoDB PDF

主流文档型数据库：MongoDB ePub

主流文档型数据库：MongoDB Mobi

版权说明

此电子书教程的全部内容，如无特别说明，均为本人原创和整理。其中部分内容参考自网络，均已备注了出处。如有发现侵犯您版权，请通过邮箱联系我 admin 艾特 crifan.com，我会尽快删除。谢谢合作。

鸣谢

感谢我的老婆陈雪的包容理解和悉心照料，才使得我crifan有更多精力去专注技术专研和整理归纳出这些电子书和技术教程，特此鸣谢。

更多其他电子书

本人crifan还写了其他100+本电子书教程，感兴趣可移步至：

crifan/crifan_ebook_readme: Crifan的电子书的使用说明

crifan.com，使用署名4.0国际(CC BY 4.0)协议发布 all right reserved，powered by Gitbook最后更新： 2021-09-10 09:03:04

简介

MongoDB简介

下面针对MongoDB做一下简要介绍：

MongoDB

Logo

一句话描述：一种主流的文档数据库

一种：还有其他的

其他文档型数据库：CouchDB、Amazon DynamoDB、Couchbase、MarkLogic

文档数据库：

= 面向文档的数据库 = Document-Oriented Datdabase

范畴：属于非关系型数据库

常称为：NoSQL

与之对应：

(传统的)关系型数据库：MySQL

其他的NoSQL

键值对(K/V)数据库：redis、Cassandra、LevelDB

图数椐库：Neo4j

时序数据库：InfluxDB

（全文）搜索（数据库）引擎：ElasticSearch、Solr

列式数据库：HBase

数据格式

主要：JSON

引申：BSON

其他：XML

优势

修改数据和结构很方便

直接修改JSON数据本身

对比：传统MySQL需要改表结构

引申出：容易兼容历史数据

字段不存在只是空值不会报错

复杂JSON可以描述复杂（嵌套）的数据结构

适用场景

数据量很大或者未来会变得很大

表结构不明确，且字段在不断增加

不适用场景

在不同的文档上需要添加事务支持

文档数据库不支持文档间的事务

多个文档直接需要复杂查询

例如join

起源

移动互联网兴起

不仅：数据量大（高并发），架构复杂

还要：快速响应

结论：传统MySQL类关系型数据库无法满足

出现：关系型数据库

其中最流行：MongoDB

胜出关键：易用、架构良好、功能丰富

概述

底层实现：C++

支持平台：Windows、Mac、Linux、Solaris等

编程接口API：常见语言都支持

C、C++、C#、Go、Java、Node.js、Perl、PHP、Python、Ruby、Rust、Scala、Swift

优势

高性能

富查询语言（支持 CRUD、数据聚合、文本搜索和地理空间查询）

高可靠性

自动伸缩架构

支持多存储引擎

crifan.com，使用署名4.0国际(CC BY 4.0)协议发布 all right reserved，powered by Gitbook最后更新： 2020-05-23 10:29:27

安装

安装

MongoDB有2个版本：

Community Edition = 社区版 = 免费版

Enterprise Edition = 企业版 = 收费版

下面主要介绍免费的社区版本：

MongoDB支持多种操作系统和平台，对应安装方式可参考：

Linux

各种发行版

Red Hat/CentOS

Ubuntu

Debian

SUSE

Amazon Linux

macOS

Windows

crifan.com，使用署名4.0国际(CC BY 4.0)协议发布 all right reserved，powered by Gitbook最后更新： 2020-05-23 10:38:40

Mac中安装MongoDB

Mac中安装MongoDB

接下来详细介绍Mac中如何安装MongoDB

目前免费的Community社区版MongoDB最新版是：v4.2

Mac中安装最新版MongoDB 4.2 community社区版方式：

先去：

brew tap mongodb/brew

再去安装MongoDB：

brew install mongodb-community

再去[可选]安装mongo shell：

brew install mongodb-community-shell

crifan.com，使用署名4.0国际(CC BY 4.0)协议发布 all right reserved，powered by Gitbook最后更新： 2020-07-11 08:48:38

基本用法

基本用法

安装好了MongoDB后，接下来去搞清楚如何操作MongoDB。

操作和使用MongoDB的基本逻辑都是：

启动MongoDB的服务端

用某种Client去操作MongoDB

根据类型分，常见Client有3种方式

命令行

MongoDB自带：mongo shell

提供了一个最基础的操作数据库的方式

GUI图形界面工具

通过图形界面工具去查看和操作数据会更加直观和方便

如MongoDB Compass、Robot 3T等

API

用各种语言的代码，通过API操作数据库

如Python、Java等

接下来分别去介绍MongoDB的服务器和客户端。

基本概念

MongoDB中的一些概念和术语的含义，可以通过和SQL对比去理解：

SQL术语和概念 | MongoDB术语概念 | 解释和说明
database | database | 数据库
table | collection | 数据库表 / 集合
row | document | 数据记录行 / 文档
column | field | 数据字段 / 域
index | index | 索引
table joins |  | 表连接，MongoDB不支持
primary key | primary key | 主键，MongoDB自动将_id作为主键

crifan.com，使用署名4.0国际(CC BY 4.0)协议发布 all right reserved，powered by Gitbook最后更新： 2020-05-28 10:20:28

Server端

MongoDB的Server端

启动本地MongoDB服务

对于普通安装的MongoDB

直接在终端中运行：

mongod

对于安装的是mongodb-community

如果Mac中安装的MongoDB是mongodb-community，那么用：

brew services start mongodb-community

以及，关于MongoDB服务端的其他常见管理方式有：

启动：brew services start mongodb-community

停止：brew services stop mongodb-community

重启：brew services restart mongodb-community

查看状态：

brew services list

如何确定已运行：看到mongodb-community是started

用ps

ps -ef | grep mongod

ps aux | grep mongod

-》有输出mongod

配置

典型的MongoDB的服务端文件是：

/etc/rc.d/init.d/mongod

而其中核心配置是：

CONFIGFILE="/etc/mongod.conf"
OPTIONS=" -f $CONFIGFILE"
mongod=${MONGOD-/usr/bin/mongod}
MONGO_USER=mongod
MONGO_GROUP=mongod

对应配置文件是：

/etc/mongod.conf

内部核心参数是：

# Where and how to store data.
storage:
  dbPath: /var/lib/mongo

表示数据库存放位置是：/var/lib/mongo

启动远程服务器中的MongoDB服务

方案1：切换到mongo用户再去启动

如果是通过SSH连接的远程服务器中：

mongod的服务，是作为mongod的组和用户，去在开机时启动的，可以正常启动的话

那么自己用ssh作为root用户登录进来后，是root用户，是无法启动属于mongod:mongod的服务mongod

在当前登录用户root的情况下，换用mongd的用户去，启动mongod：

sudo -u mongod mongod -f /etc/mongod.conf

才可以。

方案2：用systemctl或service去管理mongod

如果本身已有服务可以管理mongod，则可以通过服务管理去启动：

systemctl restart mongod

等价于：

service mongod restart

crifan.com，使用署名4.0国际(CC BY 4.0)协议发布 all right reserved，powered by Gitbook最后更新： 2020-05-26 20:00:24

Client端

MongoDB的Client端

下面介绍，在启动了MongoDB的服务端之后，如何通过客户端，主要指的是各种语言和工具，去使用MongoDB。

crifan.com，使用署名4.0国际(CC BY 4.0)协议发布 all right reserved，powered by Gitbook最后更新： 2020-05-28 10:01:41

命令行shell

命令行shell

MongoDB在安装后，自带mongo shell，是个交互式终端。可以在里面以命令行方式操作数据库。

最新版需要单独安装shell

最新的社区免费版mongodb-community的shell需要单独安装

brew install mongodb-community-shell

启动mongo shell

在命令行中输入

mongo

回车后，即可进入shell界面：

基本语法

切换到想要进入的数据库

use dbToSwitch

举例：

> use log
switched to db log

确认当前所在是哪个数据库

语法：

db

举例：

> db
admin

和

> db
log

新建用户

在创建新用户之前，先要用有权限的用户，比如 admin 登录进去，才能有权限创建新用户

注：此处之前已创建过admin超级用户，所以先去登录进入

mongo --host localhost --port 32018 -u root -p P@w --authenticationDatabase admin

然后再去给还没创建的新数据库去创建新用户

需要先去切换到对应的（虽然此时还不存在的）新的数据库：

use newDbName

然后才能（在当前数据库下）创建新用户：

db.createUser({
  user: "newUserName",
  pwd: "yourPassword",
  roles: [ { role: "dbOwner", db: "newDbName" } ]
})

然后可以确认一下是否创建成功：

show users

即可看到新创建的用户。

举例

创建数据库并新增数据

举例：

过程解释：

直接use crifanDemo

> use crifanDemo
switched to db crifanDemo

即可创建新的数据库crifanDemo

> db
crifanDemo

用db查看当前所在数据库

后续用：

> db.crifanDemo.insertOne({"name": "crifan"});
{
    "acknowledged" : true,
    "insertedId" : ObjectId("5ecd08641d1e7cfaa2e1051f")
}

去真正写入数据，才会真正（自动）创建一个database。

然后再去确认数据的确已经写入，可以用find去查找当前所有数据

在输入了db.crifanDemo.find，再按Tab键，则可以自动匹配出相关命令：

> db.crifanDemo.find
db.crifanDemo.find(               db.crifanDemo.findOne(            db.crifanDemo.findOneAndReplace(
db.crifanDemo.findAndModify(      db.crifanDemo.findOneAndDelete(   db.crifanDemo.findOneAndUpdate(

然后用find可以找出当前的所有的数据：

> db.crifanDemo.find()
{ "_id" : ObjectId("5ecd08641d1e7cfaa2e1051f"), "name" : "crifan" }

再去新增一条数据：

> db.crifanDemo.insertOne({"company": "company_name"});
{
    "acknowledged" : true,
    "insertedId" : ObjectId("5ecd08831d1e7cfaa2e10520")
}

再去find即可看到数据的确增加到2条了：

> db.crifanDemo.find()
{ "_id" : ObjectId("5ecd08641d1e7cfaa2e1051f"), "name" : "crifan" }
{ "_id" : ObjectId("5ecd08831d1e7cfaa2e10520"), "company" : "company_name" }

find也支持参数查找，比如：

> db.crifanDemo.find({"name": "crifan"})
{ "_id" : ObjectId("5ecd08641d1e7cfaa2e1051f"), "name" : "crifan" }

以及支持更多其他高级用法，比如搜索条件支持正则：

> db.crifanDemo.find({"name": {$regex: "cri"}})
{ "_id" : ObjectId("5ecd08641d1e7cfaa2e1051f"), "name" : "crifan" }

更多数据查询和用法，详见后面章节：

高级搜索

想要给新的暂时还不存在的数据库log中创建用户log

具体过程是：

> use log
switched to db log
> db.createUser({
...   user: "log",
...   pwd: "NL2@18Log",
...   roles: [ { role: "dbOwner", db: "log" } ]
... })
Successfully added user: {
        "user" : "log",
        "roles" : [
                {
                        "role" : "dbOwner",
                        "db" : "log"
                }
        ]
}
> show users
{
        "_id" : "log.log",
        "user" : "log",
        "db" : "log",
        "roles" : [
                {
                        "role" : "dbOwner",
                        "db" : "log"
                }
        ]
}

清空旧用户创建新用户

查看（当前数据库的）用户：

show users;

举例

> use admin
switched to db admin
> show users
{
    "_id" : "admin.root",
    "user" : "root",
    "db" : "admin",
    "roles" : [
        {
            "role" : "root",
            "db" : "admin"
        }
    ]
}
> use gridfs

创建用户：

切换到amind数据库

清除掉admin的之前其他用户

创建一个叫root的，角色是root的用户（拥有超级管理员，操作任意其他数据库的权限）

> use admin
switched to db admin
> db.runCommand({dropAllUsersFromDatabase: 1})
{ "n" : 1, "ok" : 1 }
> db.createUser({
...     user: "root",
...     pwd: "pwd",
...     roles: [ { role: "root", db: "admin" } ]
... })
Successfully added user: {
        "user" : "root",
        "roles" : [
                {
                        "role" : "root",
                        "db" : "admin"
                }
        ]
}
> show users
{
        "_id" : "admin.root",
        "user" : "root",
        "db" : "admin",
        "roles" : [
                {
                        "role" : "root",
                        "db" : "admin"
                }
        ]
}

查看当前用户

show users

举例：

> show users
{
        "_id" : "admin.root",
        "user" : "root",
        "db" : "admin",
        "roles" : [
                {
                        "role" : "root",
                        "db" : "admin"
                }
        ]
}

删除用户

语法：

db.dropUser("userToDelete")

举例：

> db.dropUser("log")
true

删除数据库

> db.dropDatabase()
{ "dropped" : "storybook", "ok" : 1 }

从GridFS中找歌曲类型的文件

> db.fs.files.find({"metadata.resourceType": "song"}).limit(2).pretty()
{
    "_id" : ObjectId("5b21d3787f4d384d04543f6e"),
    "contentType" : "audio/x-ms-wma",
    "chunkSize" : 261120,
    "metadata" : {
        "song" : {
            "singers" : [ ]
        },
        "fitAgeStart" : 2,
        "topics" : [
            "Fingerplay",
            "Animal",
            "Weather"
        ],
        "storybook" : {
            "publisher" : "",
            "isFiction" : "",
            "lexileIndex" : "",
            "awards" : "",
            "authors" : [ ],
            "foreignCountry" : ""
        },
        "keywords" : {
            "fromName" : [
                "animal animal",
                "animal"
            ],
            "other" : [
                "Sun",
                "Rain",
                "water spout"
            ],
            "fromContent" : [ ]
        },
        "name" : "Animals, Animals",
        "resourceType" : "song",
        "mainActors" : [
            "Spider"
        ],
        "contentAbstract" : "",
        "isSeries" : true,
        "series" : {
            "number" : 1,
            "name" : "Wee Sing-Animals, Animals, Animals"
        },
        "fitAgeEnd" : 6,
        "fileInfo" : {
            "isAudio" : true,
            "contentType" : "audio/x-ms-wma",
            "name" : "Animals, Animals.wma",
            "suffix" : "wma"
        }
    },
    "filename" : "Animals, Animals.wma",
    "length" : 2277430,
    "uploadDate" : ISODate("2018-06-14T02:31:20.767Z"),
    "md5" : "b334806c280cc37c4b873a8e2a2086cd"
}
{
    "_id" : ObjectId("5b21d3787f4d384d04543f78"),
    "contentType" : "audio/x-ms-wma",
    "chunkSize" : 261120,
    "metadata" : {
        "song" : {
            "singers" : [ ]
        },
        "fitAgeStart" : 2,
        "topics" : [
            "Fingerplay",
            "Family",
            "Others"
        ],
        "storybook" : {
            "publisher" : "",
            "isFiction" : "",
            "lexileIndex" : "",
            "awards" : "",
            "authors" : [ ],
            "foreignCountry" : ""
        },
        "keywords" : {
            "fromName" : [
                "old macdonald",
                "old Macdonald farm"
            ],
            "other" : [
                "knives",
                "forks",
                "mirror",
                "table",
                "looking glass",
                "cradle"
            ],
            "fromContent" : [ ]
        },
        "name" : "Old Macdonald Had a Farm",
        "resourceType" : "song",
        "mainActors" : [
            "mother",
            "baby"
        ],
        "contentAbstract" : "",
        "isSeries" : true,
        "series" : {
            "number" : 2,
            "name" : "Wee Sing-Animals, Animals, Animals"
        },
        "fitAgeEnd" : 6,
        "fileInfo" : {
            "isAudio" : true,
            "contentType" : "audio/x-ms-wma",
            "name" : "Old Macdonald Had a Farm.wma",
            "suffix" : "wma"
        }
    },
    "filename" : "Old Macdonald Had a Farm.wma",
    "length" : 1924864,
    "uploadDate" : ISODate("2018-06-14T02:31:21.192Z"),
    "md5" : "a2b65c25d117d428beaa346b0b7e232f"
}

统计歌曲类型文件总数

> db.fs.files.find({"metadata.resourceType": "song", "metadata.fileInfo.suffix": "mp3"}).count()
378
> db.fs.files.find({"metadata.resourceType": "song", "metadata.fileInfo.suffix": "wma"}).count()
523
> db.fs.files.find({"metadata.resourceType": "song"}).count()
901

crifan.com，使用署名4.0国际(CC BY 4.0)协议发布 all right reserved，powered by Gitbook最后更新： 2020-06-18 10:06:19

GUI工具

GUI工具

MongoDB Compass

Logo

特点

官方出品

免费

颜值高

功能够用

截图

官网

MongoDB Compass — MongoDB Compass stable

Robot 3T

旧称：Robomongo

Logo

特点

免费

功能够用

截图

官网

Robo 3T | Free, open-source MongoDB GUI (formerly Robomongo)

同一家公司的另外一款收费版

Studio 3T

截图

官网

The Professional GUI, IDE & Client for MongoDB | Studio 3T

mongo4idea

PyCharm的MongoDB的插件

截图

官网

Github

dboissier/mongo4idea: MongoDB integration in Intellij

MMS=Mongo Management Studio

截图

特点

号称支持GridFS

但是支持的不完美

不支持写入

官网

Mongo Management Studio - the professional MongoDB GUI

NoSQLBooster

有免费版

也有收费版

截图

其他

VSCode支持MongoDB

部分对比

Robot 3T vs Studio 3T

Studio 3T

Migrate databases & relations between SQL & MongoDB

Auto-complete queries with IntelliShell

Drag & drop fields to visually build queries

Use SQL to query MongoDB

Build aggregation queries stage by stage

Generate driver code in 6 languages

Automate repetitive MongoDB tasks like imports

And so much more...

Robo 3T

For simple tasks

Embedded shell

Lightweight & fun

crifan.com，使用署名4.0国际(CC BY 4.0)协议发布 all right reserved，powered by Gitbook最后更新： 2020-05-26 21:33:28

MongoDB Compass

MongoDB Compass

TODO:

【已解决】MongoDB Compass中如何快速高效地刷新数据

下载和安装MongoDB Compass

根据官网介绍

Download and Install Compass — MongoDB Compass stable

去下载页面

Compass | MongoDB

下载安装包

比如Mac的是

https://downloads.mongodb.com/compass/mongodb-compass-1.14.5-darwin-x64.dmg

下载后，安装即可。安装后是：

当前版本是：1.14.5

基本使用

打开后，进入连接数据库页：

点击连接后，进入数据库列表页：

创建数据库和集合

写入数据

点击INSERT DOCUMENT：

会出现编辑数据的弹框：

输入对应的数据的key和value，如果想要新增字段，则点击左边的 加号 ➕，会弹出 Add Field after xxx：

数据的类型，除了默认的String，还支持其他类型，比如Array数组：

分别输入数组的每项的值后，点击INSERT：

即可返回列表页，看到刚插入的数据：

删除数据库

好用之处

直接编辑内容

截图举例：

字段可以很方便的折叠和展开

点击每条记录前面的箭头：

即可展开所有字段：

再次点击，即可缩回。

其他实际使用效果举例

功能特性介绍=引导页

引导页有截图介绍其好用的功能和特点，供参考：

Perfromance Charts

Sidebar Redesigned

Visualize your Schema

Build Geo Queries

Interactive Document Editor

Visual Explain Plains

Index Management

Document Validation

Improved CURD

Deployment Awareness

Query History

crifan.com，使用署名4.0国际(CC BY 4.0)协议发布 all right reserved，powered by Gitbook最后更新： 2020-05-28 10:18:05

API

通过API操作MongoDB

MongoDB支持通过API操作，支持多种语言：

C

C++

C#/.NET

Go

Java

Node.js

Perl

PHP

Python

同步模式：PyMongo

异步模式：Motor

Ruby

Scala

Swift

Rust

crifan.com，使用署名4.0国际(CC BY 4.0)协议发布 all right reserved，powered by Gitbook最后更新： 2020-05-28 10:09:07

PyMongo

PyMongo

用Python通过API操作的MongoDB，最常见的库是：PyMongo

基本使用

运行服务端：

mongod

代码中导入

import pymongo

连接Client

from pymongo import MongoClient
client = MongoClient()

如果需要，可以指定host和port：

client = MongoClient('localhost', 27017)

或者通过URI指定更多参数：

client = MongoClient('mongodb://localhost:27017/')

创建数据库：

db = client.test_database

也可以用字典属性方式访问数据库：

db = client['test-database']

访问集合：

collection = db.test_collection

也可以用字典属性方式访问集合：

collection = db['test-collection']

然后就可以正常操作了。

比如：插入（文档）数据

demoDict = {"name": "Crifan"}
new_doc_id = collection.insert_one(demoDict).inserted_id
print("new_doc_id=%s" % new_doc_id)

更多基本操作用法可官网教程：

Tutorial — PyMongo 3.9.0 documentation

更多心得和总结可参考后续章节：

PyMongo心得

资料

官网

旧

版本：<= 3.9

PyMongo教程

Tutorial — PyMongo 3.9.0 documentation

Mongo的Client

mongo_client – Tools for connecting to MongoDB — PyMongo 3.9.0 documentation

API概览

API Documentation — PyMongo 3.9.0 documentation

最新：readthedocs.io

版本：>= 3.10

PyMongo 3.10.1 Documentation — PyMongo 3.10.1 documentation

第三方

nummy/pymongo-tutorial-cn: pymongo中文教程

crifan.com，使用署名4.0国际(CC BY 4.0)协议发布 all right reserved，powered by Gitbook最后更新： 2020-05-28 10:18:55

高级用法

高级用法

此处介绍一些，相对来说属于高级的，MongoDB的用法。

crifan.com，使用署名4.0国际(CC BY 4.0)协议发布 all right reserved，powered by Gitbook最后更新： 2020-05-22 23:06:50

IP限制

IP限制

有时候为了安全，需要限定只有某个或某些IP才可以访问自己的（远端）MongoDB数据库。

这时候，就可以用上IP限制的功能了。

举例：

编辑配置文件vi /etc/mongod.conf，改为：

bindIp: 127.0.0.1,112.4.64.141 # Listen to specific IP

即可允许除了本机外的别的固定IP的访问。

添加了IP限制的mongod重启出错：Job for mongod.service failed because the control process exited with error code

不过，可能会遇到，添加了IP限制后，mongod启动出错：

Job for mongod.service failed because the control process exited with error code

的原因是：

其实有多种多样，具体的情况，需要根据实际情况去找原因，再去解决。

其中，辅助的办法是：

参考提提示的：

Job for mongod.service failed because the control process exited with error code. See "systemctl status mongod.service" and "journalctl -xe" for details.

去运行：

journalctl -xe

去看看具体的错误。

比如此处的：

Unregistered Authentication Agent for unix-process:4637:8872553

但是后来证明，无法根据此现象找到根本原因。

只是看起来像是：

端口权限方面的问题，有些人是SELINUX限制了端口导致的，而我此处没有开启SELINU，所以不是这方面的问题。

而真正解决问题的办法是：

此处主要是去看log文件

-> 从中（先后多次）找到真正的具体的错误信息

-> 然后才能知道错误原因

-> 然后才得以解决：

(1) 错误：listen(): bind() failed errno:98 Address already in use for socket: 127.0.0.1:32018

办法：停止掉mongo后再重新启动：

如果和我一样，没有root用户密码，则：reboot重启服务器

有root密码：以mongod用户去停止mongo

sudo -u mongod systemctl stop mongod

(2) 错误：getaddrinfo("112.4.64.141") failed: Name or service not known

办法：确保bindIp中多个IP中间逗号分隔时，没有空格：

bindIp: 127.0.0.1,112.4.64.141

(3) 错误：WiredTiger (13) [1523341777:968015][1095:0x7fa3cf097dc0], file:WiredTiger.wt, connection: /var/lib/mongo/WiredTiger.turtle: handle-open: open: Permission denied

办法：确认

/var/lib/mongo

其下的所有的文件，包括此处的WiredTiger.turtle，对于此处的mongod用户，要有权限

-> 可以考虑把所有文件的owner所有者，改为此处mongo 服务对应的所属用户：mongod:mongod

-> 以及后续还有另外一个相关的：

/var/lib/mongo/journal/

(4) 错误：Failed to unlink socket file /tmp/mongodb-32018.sock errno:1 Operation not permitted

办法：

删除这个sock文件：

sudo rm /tmp/mongodb-32018.sock

后，重启mongod服务，或直接重启服务器-》启动服务器会去启动mongod服务的

crifan.com，使用署名4.0国际(CC BY 4.0)协议发布 all right reserved，powered by Gitbook最后更新： 2020-05-23 20:11:08

用户和权限

用户和权限

为了数据安全，可以针对同一个数据库，以及不同的内部的集合，创建和允许不同的用户和权限，去访问。

MongoDB支持 基于用户权限的访问控制=RBAC=Role-Based Access Control`

一个用户可以有一个或多个角色Role，决定了能访问哪个数据库，能进行什么操作

如何验证权限：

方式：启动mongod时加--auth参数

方式2：设置：security.authorization

配置文件中去设置

security的authorization为enabled

在开启认证auth==开启访问控制之前，需要你在admin数据库中，创建一个是带有userAdmin或userAdminAnyDatabase权限的用户

-》否则意味着你没有一个拥有管理权限的用户，就没法创建其他普通用户了

不过对于创建用户本身来说：在开启访问控制之前或者之后，都是可以的。

关于权限的详细解释如下：

Authentication Database

创建一个用户的时候，需要制定对应数据库的

这个数据库就是该用户的Authentication Database

不过一个用户的权限，可以不限定Authentication Database，只要针对别的数据库给了相应权限即可

创建用户

主要含义：增加一个用户，对于某个资源resource，允许某些操作action（就有了某些权限privilege）

resource：

典型的只有一个db

也可以针对其他的，比如collection：

{ db: "products", collection: "inventory" }

典型写法：

createUser

其中参数：

role的参数：

可以用系统内置的，比如：

read

readWrite

dbAdmin

dbOwner

userAdmin

也可以用用户自定义的role

在创建用户时没有指定对应role的话，可以后续用：grantRolesToUser去额外加上role

用户的唯一标识是： 用户名+授权数据库

换句话说：如果在创建用户时，两个用户名一样，但是授权数据库不同，也是不同的用户

如果想要用一个用户对多个数据库都有权限，那么应该是：创建单个用户，带上对应角色role，而这个role是允许访问多个数据库的

MongoDB中是把所有用户相关信息都保存到admin数据库中的system.users中了

包括：用户名，密码，用户的授权数据库

不建议直接操作该数据库，而建议（在mongo shell中）用用户管理命令，比如：

createUser

grantRolesToUser

usersInfo

等等

认证Authentication和授权Authorization

官网总结：

Authentication verifies the identity of a user

Authorization determines the verified user’s access to resources and operations

自己想到的比喻：

Authentication=认证=识别用户（的身份）：是否是之前添加过（认识的）的用户，否则不让进

就像要进去一间屋子，需要一把钥匙

对于Mongo shell：

需要提供：

用户名username

密码password

对应的哪个数据库database

对应着 mongo shell（或其他mongo API）的参数：

--username <username>, -u <username>

--password <password>, -p <password>

--authenticationDatabase <dbname>

或者，先进去，再认证：

先运行mongo，在shell里再去:

use xxxDb

db.auth("username", "password")

而对于其他语言的Driver

Python

pymongo

MongoClient初始化时传递对应参数即可

  mongoClient = MongoClient(
      host="11.22.33.44",
      port=27017,
      username="usr",
      password="pwd"
  )

或者是用Mongo URI，比如：

  mongodb://usr:pwd@11.22.33.44:27017/dbName

Authorization=授权=判断用户能干嘛：针对哪个数据库，有哪些操作权限

就像进了一间屋子，到底能进哪间房，且每间房里只能允许能干什么事

不能进别的房间，进了允许进的房间后，也不能干不允许干的事

crifan.com，使用署名4.0国际(CC BY 4.0)协议发布 all right reserved，powered by Gitbook最后更新： 2020-05-26 20:34:11

心得和总结

心得和总结

下面总结一些在MongoDB使用期间的心得和注意事项等内容。

先列出一些小的心得

导入数据之前，确保ID不能重复，否则会由于ID重复而无法覆盖

之前某次去恢复数据，故意没有删除本地之前已有（同样但是旧的）数据：

看看导入能否直接覆盖，结果由于ID重复而报错，覆盖失败：

  - E11000 duplicate key error collection: storybook.main index: _id_ dup key: { : ObjectId('5bd7be33bfaa44fe2c73bda2') }

^C2018-12-06T11:02:12.531+0800    signal 'interrupt' received; attempting to shut down
2018-12-06T11:02:12.560+0800    error: multiple errors in bulk operation:
  - E11000 duplicate key error collection: storybook.scholastic index: _id_ dup key: { : ObjectId('5bc71849bfaa4425b7ea8082') }
  - E11000 duplicate key error collection: storybook.scholastic index: _id_ dup key: { : ObjectId('5bc7184dbfaa4425b7ea8083') }
  - E11000 duplicate key error collection: storybook.scholastic index: _id_ dup key: { : ObjectId('5bc7184dbfaa4425b7ea8084') }

crifan.com，使用署名4.0国际(CC BY 4.0)协议发布 all right reserved，powered by Gitbook最后更新： 2020-05-26 21:13:03

PyMongo心得

PyMongo心得

此处整理Python语言操作MongoDB的常用的库PyMongo的一些使用心得。

crifan.com，使用署名4.0国际(CC BY 4.0)协议发布 all right reserved，powered by Gitbook最后更新： 2020-05-23 12:13:59

生成URI

生成URI

在开发期间，可能会涉及到，从配置中生成MongoDB的URI

下面代码供参考使用

def generateMongoUri(host=None,
                port=None,
                isUseAuth=False,
                username=None,
                password=None,
                authSource=None,
                authMechanism=None):
    """"generate mongodb uri"""
    mongodbUri = ""

    if not host:
        # host = "127.0.0.0"
        host = "localhost"

    if not port:
        port = 27017

    mongodbUri = "mongodb://%s:%s" % (
        host, \
        port
    )
    # 'mongodb://localhost:27017'
    # 'mongodb://ip:27017'

    if isUseAuth:
        mongodbUri = "mongodb://%s:%s@%s:%s" % (
            quote_plus(username), \
            quote_plus(password), \
            host, \
            port \
        )
        print(mongodbUri)

        if authSource:
            mongodbUri = mongodbUri + ("/%s" % authSource)
            print("mongodbUri=%s" % mongodbUri)

        if authMechanism:
            mongodbUri = mongodbUri + ("?authMechanism=%s" % authMechanism)
            print("mongodbUri=%s" % mongodbUri)

    print("return mongodbUri=%s" % mongodbUri)
    #mongodb://username:quoted_password@host:port/authSource?authMechanism=authMechanism
    #mongodb://localhost:27017

    return mongodbUri

调用举例：

from pymongo import MongoClient

mongoUri = generateMongoUri(
    host=MONGODB_HOST,
    port=int(MONGODB_PORT),
    username=MONGODB_USERNAME,
    password=MONGODB_PASSWORD,
    authSource=MONGODB_AUTH_SOURCE,
    authMechanism=MONGODB_AUTH_MECHANISM,
)
mongoClient = MongoClient(mongoUri)

crifan.com，使用署名4.0国际(CC BY 4.0)协议发布 all right reserved，powered by Gitbook最后更新： 2020-05-23 20:26:42

插入新增记录

插入新增记录

举例：

insertResult = questionCollection.insert_one(newQuestion)
newQuestionIdObj = insertResult.inserted_id
log.debug("newQuestionIdObj=%s", newQuestionIdObj)

类似的用Postman通过API调用效果：

插入后的数据在MongoDB Compass的显示效果：

crifan.com，使用署名4.0国际(CC BY 4.0)协议发布 all right reserved，powered by Gitbook最后更新： 2020-05-23 12:16:07

设置时间范围等查询条件

设置时间范围等查询条件

代码：

import pymongo
import datetime

curTime = datetime.datetime.now()
# timeKeyName = "start_time"
timeKeyName = "finish_time"
earliestTime = curTime - datetime.timedelta(days = 180)
userEvaluations = evalCollection.find({
    "user_id": userId,
    timeKeyName: {
        "$gte": earliestTime,
        "$lte": curTime
    }
}).sort(timeKeyName, pymongo.DESCENDING).limit(20)
userEvaluationList = list(userEvaluations)
userEvaluationList.reverse()
historyList = []
for eachEvaluation in userEvaluationList:
    if "overall_level" in eachEvaluation:
        curTimeLevelDict = {
            "time": eachEvaluation[timeKeyName],
            "overall_level": eachEvaluation["overall_level"]
        }
        historyList.append(curTimeLevelDict)
log.debug("historyList=%s", historyList)

实现了期望的逻辑：

去mongodb查询

最早半年前，最晚当前时间

结果中再去根据时间倒序

然后再去取最多20个

从而实现：最近半年，最多20个，只不过顺序是反的而已

对于时间倒序后的结果，再调换顺序

即可得到需要的：最近半年的，最多20个，按照时间升序排列

然后输出希望的结果：

crifan.com，使用署名4.0国际(CC BY 4.0)协议发布 all right reserved，powered by Gitbook最后更新： 2020-05-23 12:10:57

备份和恢复

备份和恢复

MongoDB数据库，支持导出数据到文件，也支持从数据库文件导入，对应着备份和恢复。

与之对应，MongoDB提供了两个成对的配套的工具：

mongodump和mongorestore

mongoexport和mongoimport

下面详细介绍一下区别和具体用法。

mongodump/mongorestore和mongoimport/mongoexport的区别

概述=结论：

mongodump和mongorestore：适合整个database，甚至所有database的数据的备份和恢复

导出数据格式是：bson

mongoexport和mongoimport：适合单个database的单个collection的数据备份和恢复

支持导入格式是：json

详解：

背景知识

JSON vs BSON

MongoDB内部数据保存用BSON

原因：JSON是BSON的子集

-> 部分数据类型无法用JSON保存

-> 所以如果导出为JSON格式，可能会丢失部分复杂的数据类型的数据

区别和对比

mongodump/mongorestore
mongoimport/mongoexport

导出格式
BSON
JSON

主要用途
简单且高效的 小型的MongoDB的数据库的备份/恢复
小规模的或部分的Mongo的数据的，测试期间的数据备份/恢复

额外说明
不适合备份/恢复 大型MongoDB数据库
mongodump不导出local（这个特殊的）数据库
mongodump不导出index索引
导出数据时使用严格模式（strict mode representation=MongoDB Extended JSON )仅支持UTF-8编码的数据

经验和结论
支持普通导出单个db的所有的collection
建议：普通的，简单的，数据的备份和恢复，都还是用mongodump/mongorestore这套工具
不支持普通导出单个db的所有的collection

其他相关

如果是在线云平台部署的Mongo，备份/恢复可以使用

MongoDB Atlas

Fully Managed MongoDB, hosted on AWS, Azure, and GCP | MongoDB

如果是replica sets，备份/恢复可以使用：

MongoDB Cloud Manager

或

Ops Manager

crifan.com，使用署名4.0国际(CC BY 4.0)协议发布 all right reserved，powered by Gitbook最后更新： 2021-09-09 09:12:27

mongodump和mongorestore

mongodump和mongorestore

概述：

mongodump

导出整个数据库(db)

mongodump -d databaseName -o outputFolder

输出目录如果是：当前目录.

mongodump -d databaseName -o .

导出数据库(db)中某个集合(Collection)=子表

mongodump -d databaseName -c CollectionName -o outputFolder

输出目录如果是：当前目录.

mongodump -d databaseName -c CollectionName -o .

其他说明

导出的单个collection文件名一般是collectionName.bson和collectionName.metadata.json

mongorestore

恢复（导入）某个目录下的某个数据库(db)中的所有的集合(collection)

mongorestore -d databaseName ./localSubFoler

说明：当前目录localSubFoler中有一个或多个*.bson(以及对应的*.metadata.json)

举例

mongorestore -d storybook ./storybook

恢复（导入）某个数据库(db)中的单个集合(collection)

mongorestore -d databaseName -c CollectionName subFolder/someCollection.bson

注：mongorestore从文件导入数据的话，不支持JSON文件，只支持BSON文件

且是用mongodump导出的BSON文件

举例

mongorestore -d storybook -c lexile ./storybook/lexile.bson

通用参数

额外指定host和port

举例

mongorestore -h localhost --port 32018 -d storybook ./storybook

额外指定（对应数据库和表的）用户名和密码

举例

mongorestore -h localhost --port 32018 -u storybook -p yourPassword -d storybook ./storybook

详解：

mongodump备份

某次导出的命令：

  master  mongodump -d shortLink -c gameShortLink -o .
2021-09-10T08:58:12.258+0800    writing shortLink.gameShortLink to shortLink/gameShortLink.bson
2021-09-10T08:58:12.306+0800    done dumping shortLink.gameShortLink (900 documents)
  master  mongodump -d shortLink -c parsedPureShortLink -o .
2021-09-10T08:58:21.449+0800    writing shortLink.parsedPureShortLink to shortLink/parsedPureShortLink.bson
2021-09-10T08:58:21.451+0800    done dumping shortLink.parsedPureShortLink (14 documents)

导出后的文件：

  master  ll
total 0
drwxr-xr-x  6 limao  1748468295   192B  9 10 08:58 shortLink
  master  ll shortLink
total 16224
-rw-r--r--  1 limao  1748468295   7.8M  9 10 08:58 gameShortLink.bson
-rw-r--r--  1 limao  1748468295   871B  9 10 08:58 gameShortLink.metadata.json
-rw-r--r--  1 limao  1748468295   131K  9 10 08:58 parsedPureShortLink.bson
-rw-r--r--  1 limao  1748468295   223B  9 10 08:58 parsedPureShortLink.metadata.json

导出 本地MongoDB 的某表到当前文件夹

mongodump -d storybook -o .

导出 本地MongoDB 某表中某集合到当前文件夹，且指定host和port

mongodump -h 127.0.0.1 --port 27017 -d Scholastic -c Storybook -o .

导出 远程阿里云的MongoDB 某表中某集合到当前文件夹，且指定host和port，以及指定用户名和密码

mongodump --host dds-xxx.mongodb.rds.aliyuncs.com --port xxx --authenticationDatabase admin -u root -p xxx -d exercise -o .

参数解释：

-d=--database：数据库 Scholastic

-c=--collection：集合=表，Storybook

--type：默认为json

所以此处可以不传此参数，用默认值

-o==--out：. 表示 当前文件夹

shell输出：

Scholastic
    Storybook.bson # 数据文件, 60M
    Storybook.metadata.json # 元数据, 130B

举例：

[root@xxx-general-01 exercise]# mongodump --host dds-xxx.mongodb.rds.aliyuncs.com --port xxx --authenticationDatabase admin -u root -p xxx -d exercise -o .
2019-03-07T11:30:24.036+0800    writing exercise.storybook to
2019-03-07T11:30:24.037+0800    writing exercise.unit to
2019-03-07T11:30:24.037+0800    writing exercise.dialog to
2019-03-07T11:30:24.037+0800    writing exercise.audio.files to
2019-03-07T11:30:24.038+0800    done dumping exercise.storybook (2 documents)
2019-03-07T11:30:24.038+0800    writing exercise.audio.chunks to
2019-03-07T11:30:24.038+0800    done dumping exercise.unit (1 document)
2019-03-07T11:30:24.039+0800    done dumping exercise.audio.chunks (1 document)
2019-03-07T11:30:24.047+0800    done dumping exercise.audio.files (1 document)
2019-03-07T11:30:24.048+0800    done dumping exercise.dialog (1 document)
[root@xxx-general-01 exercise]# ll
total 4
drwxr-xr-x 2 root root 4096 Mar  7 11:30 exercise
[root@xxx-general-01 exercise]# ll exercise/
total 60
-rw-r--r-- 1 root root 20737 Mar  7 11:30 audio.chunks.bson
-rw-r--r-- 1 root root   195 Mar  7 11:30 audio.chunks.metadata.json
-rw-r--r-- 1 root root   249 Mar  7 11:30 audio.files.bson
-rw-r--r-- 1 root root   197 Mar  7 11:30 audio.files.metadata.json
-rw-r--r-- 1 root root   554 Mar  7 11:30 dialog.bson
-rw-r--r-- 1 root root    87 Mar  7 11:30 dialog.metadata.json
-rw-r--r-- 1 root root   834 Mar  7 11:30 storybook.bson
-rw-r--r-- 1 root root    90 Mar  7 11:30 storybook.metadata.json
-rw-r--r-- 1 root root   309 Mar  7 11:30 unit.bson
-rw-r--r-- 1 root root    85 Mar  7 11:30 unit.metadata.json

另附上，之前某次导出的数据的文件如下：

mongodump语法help帮助

➜  output git:(master) ✗ mongodump --help
Usage:
  mongodump <options>

Export the content of a running server into .bson files.

Specify a database with -d and a collection with -c to only dump that database or collection.

See http://docs.mongodb.org/manual/reference/program/mongodump/ for more information.

general options:
      --help                                                print usage
      --version                                             print the tool version and exit

verbosity options:
  -v, --verbose=<level>                                     more detailed log output (include multiple times for more verbosity, e.g. -vvvvv, or specify a
                                                            numeric value, e.g. --verbose=N)
      --quiet                                               hide all log output

connection options:
  -h, --host=<hostname>                                     mongodb host to connect to (setname/host1,host2 for replica sets)
      --port=<port>                                         server port (can also use --host hostname:port)

ssl options:
      --ssl                                                 connect to a mongod or mongos that has ssl enabled
      --sslCAFile=<filename>                                the .pem file containing the root certificate chain from the certificate authority
      --sslPEMKeyFile=<filename>                            the .pem file containing the certificate and key
      --sslPEMKeyPassword=<password>                        the password to decrypt the sslPEMKeyFile, if necessary
      --sslCRLFile=<filename>                               the .pem file containing the certificate revocation list
      --sslAllowInvalidCertificates                         bypass the validation for server certificates
      --sslAllowInvalidHostnames                            bypass the validation for server name
      --sslFIPSMode                                         use FIPS mode of the installed openssl library

authentication options:
  -u, --username=<username>                                 username for authentication
  -p, --password=<password>                                 password for authentication
      --authenticationDatabase=<database-name>              database that holds the user's credentials
      --authenticationMechanism=<mechanism>                 authentication mechanism to use

namespace options:
  -d, --db=<database-name>                                  database to use
  -c, --collection=<collection-name>                        collection to use

uri options:
      --uri=mongodb-uri                                     mongodb uri connection string

query options:
  -q, --query=                                              query filter, as a JSON string, e.g., '{x:{$gt:1}}'
      --queryFile=                                          path to a file containing a query filter (JSON)
      --readPreference=<string>|<json>                      specify either a preference name or a preference json object
      --forceTableScan                                      force a table scan

output options:
  -o, --out=<directory-path>                                output directory, or '-' for stdout (defaults to 'dump')
      --gzip                                                compress archive our collection output with Gzip
      --repair                                              try to recover documents from damaged data files (not supported by all storage engines)
      --oplog                                               use oplog for taking a point-in-time snapshot
      --archive=<file-path>                                 dump as an archive to the specified path. If flag is specified without a value, archive is written
                                                            to stdout
      --dumpDbUsersAndRoles                                 dump user and role definitions for the specified database
      --excludeCollection=<collection-name>                 collection to exclude from the dump (may be specified multiple times to exclude additional
                                                            collections)
      --excludeCollectionsWithPrefix=<collection-prefix>    exclude all collections from the dump that have the given prefix (may be specified multiple times
                                                            to exclude additional prefixes)
  -j, --numParallelCollections=                             number of collections to dump in parallel (4 by default) (default: 4)
      --viewsAsCollections                                  dump views as normal collections with their produced data, omitting standard collections

mongorestore恢复

举例：

从某个目录，导入整个database：

➜  from_server ll
total 48
drwxr-xr-x  12 crifan  staff   384B  3  7 11:30 exercise
-rw-r--r--@  1 crifan  staff    20K  3  7 11:32 exercise_290307.zip
➜  from_server ll exercise
total 120
-rw-r--r--  1 crifan  staff    20K  3  7 11:30 audio.chunks.bson
-rw-r--r--  1 crifan  staff   195B  3  7 11:30 audio.chunks.metadata.json
-rw-r--r--  1 crifan  staff   249B  3  7 11:30 audio.files.bson
-rw-r--r--  1 crifan  staff   197B  3  7 11:30 audio.files.metadata.json
-rw-r--r--  1 crifan  staff   554B  3  7 11:30 dialog.bson
-rw-r--r--  1 crifan  staff    87B  3  7 11:30 dialog.metadata.json
-rw-r--r--  1 crifan  staff   834B  3  7 11:30 storybook.bson
-rw-r--r--  1 crifan  staff    90B  3  7 11:30 storybook.metadata.json
-rw-r--r--  1 crifan  staff   309B  3  7 11:30 unit.bson
-rw-r--r--  1 crifan  staff    85B  3  7 11:30 unit.metadata.json
➜  from_server mongorestore -d exercise ./exercise
2019-03-07T11:51:15.303+0800    the --db and --collection args should only be used when restoring from a BSON file. Other uses are deprecated and will not exist in the future; use --nsInclude instead
2019-03-07T11:51:15.305+0800    building a list of collections to restore from exercise dir
2019-03-07T11:51:15.308+0800    reading metadata for exercise.audio.chunks from exercise/audio.chunks.metadata.json
2019-03-07T11:51:15.309+0800    reading metadata for exercise.storybook from exercise/storybook.metadata.json
2019-03-07T11:51:15.309+0800    reading metadata for exercise.dialog from exercise/dialog.metadata.json
2019-03-07T11:51:15.310+0800    reading metadata for exercise.unit from exercise/unit.metadata.json
2019-03-07T11:51:15.585+0800    restoring exercise.unit from exercise/unit.bson
2019-03-07T11:51:15.678+0800    restoring exercise.storybook from exercise/storybook.bson
2019-03-07T11:51:15.760+0800    restoring exercise.dialog from exercise/dialog.bson
2019-03-07T11:51:15.846+0800    restoring exercise.audio.chunks from exercise/audio.chunks.bson
2019-03-07T11:51:15.851+0800    no indexes to restore
2019-03-07T11:51:15.851+0800    finished restoring exercise.dialog (1 document)
2019-03-07T11:51:15.851+0800    no indexes to restore
2019-03-07T11:51:15.851+0800    finished restoring exercise.unit (1 document)
2019-03-07T11:51:15.858+0800    restoring indexes for collection exercise.audio.chunks from metadata
2019-03-07T11:51:15.860+0800    no indexes to restore
2019-03-07T11:51:15.860+0800    finished restoring exercise.storybook (2 documents)
2019-03-07T11:51:15.864+0800    reading metadata for exercise.audio.files from exercise/audio.files.metadata.json
2019-03-07T11:51:15.930+0800    finished restoring exercise.audio.chunks (1 document)
2019-03-07T11:51:16.029+0800    restoring exercise.audio.files from exercise/audio.files.bson
2019-03-07T11:51:16.031+0800    restoring indexes for collection exercise.audio.files from metadata
2019-03-07T11:51:16.077+0800    finished restoring exercise.audio.files (1 document)
2019-03-07T11:51:16.077+0800    done
➜  from_server

导入单个collection：

➜  mongodb_migration git:(master) pwd
/Users/crifan/xxx/pyspider_migration/mongodb_migration
➜  mongodb_migration git:(master) ll storybook
total 416536
-rw-r--r--  1 crifan  staff    34M 11 26 11:58 lexile.bson
-rw-r--r--  1 crifan  staff   130B 11 26 11:58 lexile.metadata.json
-rw-r--r--  1 crifan  staff   106M 11 26 11:58 main.bson
-rw-r--r--  1 crifan  staff   128B 11 26 11:58 main.metadata.json
-rw-r--r--  1 crifan  staff    62M 11 26 11:58 scholastic.bson
-rw-r--r--  1 crifan  staff   134B 11 26 11:58 scholastic.metadata.json
➜  mongodb_migration git:(master) mongorestore -d storybook -c lexile ./storybook/lexile.bson
2019-01-03T14:58:44.324+0800    checking for collection data in storybook/lexile.bson
2019-01-03T14:58:44.328+0800    reading metadata for storybook.lexile from storybook/lexile.metadata.json
2019-01-03T14:58:44.480+0800    restoring storybook.lexile from storybook/lexile.bson
2019-01-03T14:58:45.166+0800    no indexes to restore
2019-01-03T14:58:45.166+0800    finished restoring storybook.lexile (29911 documents)
2019-01-03T14:58:45.166+0800    done

已有一个之前用mongodump备份出来的文件夹：evaluation，其中保存了整个evaluation的database的数据，将其恢复到此处本地的mongodb数据库

➜  mongodb mongorestore -d evaluation ./evaluation
2018-12-21T13:36:00.173+0800    the --db and --collection args should only be used when restoring from a BSON file. Other uses are deprecated and will not exist in the future; use --nsInclude instead
2018-12-21T13:36:00.175+0800    building a list of collections to restore from evaluation dir
2018-12-21T13:36:00.176+0800    reading metadata for evaluation.image.chunks from evaluation/image.chunks.metadata.json
2018-12-21T13:36:00.176+0800    reading metadata for evaluation.question from evaluation/question.metadata.json
2018-12-21T13:36:00.176+0800    reading metadata for evaluation.audio.chunks from evaluation/audio.chunks.metadata.json
2018-12-21T13:36:00.274+0800    restoring evaluation.image.chunks from evaluation/image.chunks.bson
2018-12-21T13:36:00.277+0800    reading metadata for evaluation.image.files from evaluation/image.files.metadata.json
2018-12-21T13:36:00.393+0800    restoring evaluation.audio.chunks from evaluation/audio.chunks.bson
2018-12-21T13:36:00.475+0800    restoring evaluation.question from evaluation/question.bson
2018-12-21T13:36:00.571+0800    restoring evaluation.image.files from evaluation/image.files.bson
2018-12-21T13:36:00.579+0800    restoring indexes for collection evaluation.audio.chunks from metadata
2018-12-21T13:36:00.653+0800    finished restoring evaluation.audio.chunks (1 document)
2018-12-21T13:36:00.654+0800    reading metadata for evaluation.audio.files from evaluation/audio.files.metadata.json
2018-12-21T13:36:00.739+0800    restoring evaluation.audio.files from evaluation/audio.files.bson
2018-12-21T13:36:00.747+0800    no indexes to restore
2018-12-21T13:36:00.747+0800    finished restoring evaluation.question (880 documents)
2018-12-21T13:36:00.747+0800    restoring indexes for collection evaluation.audio.files from metadata
2018-12-21T13:36:00.823+0800    finished restoring evaluation.audio.files (1 document)
2018-12-21T13:36:00.825+0800    restoring indexes for collection evaluation.image.files from metadata
2018-12-21T13:36:00.932+0800    finished restoring evaluation.image.files (663 documents)
2018-12-21T13:36:03.167+0800    [##############..........]  evaluation.image.chunks  222MB/357MB  (62.1%)
2018-12-21T13:36:04.849+0800    [########################]  evaluation.image.chunks  357MB/357MB  (100.0%)
2018-12-21T13:36:04.849+0800    restoring indexes for collection evaluation.image.chunks from metadata
2018-12-21T13:36:04.974+0800    finished restoring evaluation.image.chunks (1829 documents)
2018-12-21T13:36:04.974+0800    done

导入后的MongoDB Compass中数据效果：

带指定用户名和密码的

[root@xxx-general-01 for_backup_mongodb]# mongorestore -h localhost --port 32018 -u storybook -p pwd -d storybook ./storybook
2018-10-30T13:59:21.040+0800    building a list of collections to restore from storybook dir
2018-10-30T13:59:21.041+0800    reading metadata for storybook.scholastic from storybook/scholastic.metadata.json
2018-10-30T13:59:21.041+0800    reading metadata for storybook.main from storybook/main.metadata.json
2018-10-30T13:59:21.061+0800    restoring storybook.main from storybook/main.bson
2018-10-30T13:59:21.075+0800    restoring storybook.scholastic from storybook/scholastic.bson
2018-10-30T13:59:22.567+0800    restoring indexes for collection storybook.scholastic from metadata
2018-10-30T13:59:22.567+0800    finished restoring storybook.scholastic (51785 documents)
2018-10-30T13:59:22.629+0800    restoring indexes for collection storybook.main from metadata
2018-10-30T13:59:22.629+0800    finished restoring storybook.main (51785 documents)
2018-10-30T13:59:22.629+0800    done

crifan.com，使用署名4.0国际(CC BY 4.0)协议发布 all right reserved，powered by Gitbook最后更新： 2021-09-10 09:02:23

mongoexport和mongoimport

mongoexport和mongoimport

基本语法：

mongoimport -d database_name -c collection_name --file exported_mongodb_collection_file.json

举例

导出数据库evaluation的集合question

mongoimport -d evaluation -c question --file questions_181219_2.json

导出和恢复authority

背景：

Mac中MongoDB中有如下数据：

然后去导出：

单个database数据库forecast中某个特定的collection集合authority的数据

mongoexport -d forecast -c authority -o forcast.authority_20200628.json

具体log：

limao@xxx  ~/Downloads/mongo_data  mongoexport -d forecast -c authority -o forcast.authority_20200628.json
2020-06-28T16:26:15.600+0800    connected to: mongodb://localhost/
2020-06-28T16:26:15.614+0800    exported 2 records
limao@xxx  ~/Downloads/mongo_data  ll
total 8
-rw-r--r--  1 limao  CORP\Domain Users   126B  6 28 16:26 forcast.authority_20200628.json

然后把此json文件弄到Win中VMWare中的macOS之后，再去恢复：

mongoimport -d forecast -c authority --file forcast.authority_20200628.json

具体log：

crifanli@crifanlideMac  /Volumes/VMware Shared Folders/share_macOS  mongoimport -d forecast -c authority --file forcast.authority_20200628.json
2020-06-28T01:31:10.734-0700    connected to: mongodb://localhost/
2020-06-28T01:31:10.742-0700    2 document(s) imported successfully. 0 document(s) failed to import.

Win中（能连接到macOS中MongoDB的）mongo的GUI客户端Robot 3T中，刷新后即可看到导入的数据：

crifan.com，使用署名4.0国际(CC BY 4.0)协议发布 all right reserved，powered by Gitbook最后更新： 2021-09-09 09:01:40

新建空数据库和集合

新建空数据库和空集合

想要新建一个空的MongoDB的数据库，以及在空数据库中创建一个空的集合。

思路是：新建一个db，给db插入一个值，再删掉，就得到空的db的collection（和空的db数据库）了。

具体做法：

use newDb
db.newCollection.insert({"fakeKey": "fakeValue"})
db.newCollection.find() # 会输出刚插入的记录的_id
db.newCollection.deleteOne({"_id": ObjectId("newInsertedId")})

然后用：

db.newCollection.find()

会看到输出是空的 -》 说明的确已经新建一个空的db和空的collection了。

提示：

在此期间可以随时用：

db

查看当前所处的数据库

和

show dbs

看看当前有哪些数据库

和：

show collections

看看当前数据库中有哪些集合

举例：新建一个db=storybook和collection=main

步骤：

> use storybook
switched to db storybook
> show dbs
admin    0.000GB
dialog   0.272GB
gridfs  13.869GB
local    0.000GB
> db.main.insert({"fakeKey": "fakeValue"})
WriteResult({ "nInserted" : 1 })
> show collections
main
> db
storybook
> db.main.find()
{ "_id" : ObjectId("5bd2bddb6ec5fdeabfbd6ecb"), "fakeKey" : "fakeValue" }
> db.main.deleteOne({"_id": ObjectId("5bd2bddb6ec5fdeabfbd6ecb")})
{ "acknowledged" : true, "deletedCount" : 1 }
> db.main.find()
>

crifan.com，使用署名4.0国际(CC BY 4.0)协议发布 all right reserved，powered by Gitbook最后更新： 2020-05-23 22:04:37

如何更新数据

如何更新数据

对于已有一个MongoDB的记录，想要去更新其中的部分数据，有如下几种方式：

MongoDB shell

官网举例

db.col.update( { "count" : { $gt : 5 } } , { $set : { "test5" : "OK"} },true,true );

举例：设置active为Y

mongo shell中去插入新字段

db.question.update({}, {$set: {"active": "Y"}}, {upsert: false, multi: true})

输出：

> db.question.update({}, {$set: {"active": "Y"}}, {upsert: false, multi: true})
WriteResult({ "nMatched" : 883, "nUpserted" : 0, "nModified" : 883 })

效果：

pymongo

通过PyMongo去更新某个记录的部分数据

举例：

        insertResult = mongoDstCollection.insert_one(dstBookInfo)
        logging.debug("insertResult=%s", insertResult)
        newDstRecordId = insertResult.inserted_id
        logging.debug("newDstRecordId=%s", newDstRecordId)
        # update inserted id into existing old source record
        mergedId = ""
        if newDstRecordId:
            mergedId = str(newDstRecordId)
        logging.debug("mergedId=%s", mergedId) # '5bd28426bfaa44216e98a496'
        updateResult = mongoSrcCollection.update_one(filter={"_id": curSrcBookIdOjb}, update={"$set": {"mergedId": mergedId}})
        logging.debug("updateResult=%s", updateResult)
        matched_count = updateResult.matched_count
        modified_count = updateResult.modified_count
        logging.debug("matched_count=%s, modified_count=%s", matched_count, modified_count)

crifan.com，使用署名4.0国际(CC BY 4.0)协议发布 all right reserved，powered by Gitbook最后更新： 2020-05-23 20:37:04

高级搜索

高级搜索

下面介绍在搜索和查询想要的记录时，涉及到的一些高级搜索技巧，尤其是正则搜索和嵌套搜索。

搜索期间的条件组合

背景：搜索数据期间，可能会用到多种条件，不同条件，可能需要组合在一起。

对于组合的种类和语法，详见官网：

Operators — MongoDB Manual

->

Query and Projection Operators — MongoDB Manual

先列出有哪些类型：

Comparison

$eq

Matches values that are equal to a specified value.

$gt

Matches values that are greater than a specified value.

$gte

Matches values that are greater than or equal to a specified value.

$in

Matches any of the values specified in an array.

$lt

Matches values that are less than a specified value.

$lte

Matches values that are less than or equal to a specified value.

$ne

Matches all values that are not equal to a specified value.

$nin

Matches none of the values specified in an array.

Logical

$and

Joins query clauses with a logical AND returns all documents that match the conditions of both clauses.

$not

Inverts the effect of a query expression and returns documents that do not match the query expression.

$nor

Joins query clauses with a logical NOR returns all documents that fail to match both clauses.

$or

Joins query clauses with a logical OR returns all documents that match the conditions of either clause.

Element

$exists

Matches documents that have the specified field.

$type

Selects documents if a field is of the specified type.

Evaluation

$expr

Allows use of aggregation expressions within the query language.

$jsonSchema

Validate documents against the given JSON Schema.

$mod

Performs a modulo operation on the value of a field and selects documents with a specified result.

$regex

Selects documents where values match a specified regular expression.

$text

Performs text search.

$where

Matches documents that satisfy a JavaScript expression.

Geospatial

$geoIntersects

Selects geometries that intersect with a GeoJSON geometry. The 2dsphere index supports$geoIntersects.

$geoWithin

Selects geometries within a bounding GeoJSON geometry. The 2dsphere and 2d indexes support $geoWithin.

$near

Returns geospatial objects in proximity to a point. Requires a geospatial index. The 2dsphereand 2d indexes support $near.

$nearSphere

Returns geospatial objects in proximity to a point on a sphere. Requires a geospatial index. The 2dsphere and 2d indexes support $nearSphere.

Array

$all

Matches arrays that contain all elements specified in the query.

$elemMatch

Selects documents if element in the array field matches all the specified $elemMatch conditions.

$size

Selects documents if the array field is a specified size.

Bitwise

$bitsAllClear

Matches numeric or binary values in which a set of bit positions all have a value of 0.

$bitsAllSet

Matches numeric or binary values in which a set of bit positions all have a value of 1.

$bitsAnyClear

Matches numeric or binary values in which any bit from a set of bit positions has a value of 0.

$bitsAnySet

Matches numeric or binary values in which any bit from a set of bit positions has a value of 1.

Comments

$comment

Adds a comment to a query predicate.

Projection Operators

$

Projects the first element in an array that matches the query condition.

$elemMatch

Projects the first element in an array that matches the specified $elemMatch condition.

$meta

Projects the document’s score assigned during $text operation.

$slice

Limits the number of elements projected from an array. Supports skip and limit slices.

可以根据需要选择合适的组合方式。

举例：

db.inventory.find( { $or: [ { quantity: { $lt: 20 } }, { price: 10 } ] } )

和：

var cursor = db.collection('inventory').find({
  $or: [ {status: "A" }, { qty: { $lt: 30 } } ]
});

列表子元素搜索

如果是搜索list中所有的元素，即不关心list中具体是第几个元素，那么就直接写成：

mainField.subFieldList

如果要关心具体是哪个位置的元素的值，则使用：.N

比如 第一个是

mainField.subFieldList.0

而更加复杂的组合，可以用到：

$size

表示list的个数

$all

表示所有的

$elemMatch

即可。

更多语法细节可参考：

Array Query Operators — MongoDB Manual

字段嵌套搜索

用 点 . 实现字段的嵌套的搜索：

举例：搜索子字段sub_questions的options的option_text

对于内容：

{
  "_id": "5c1777e1cc6df4563adf4a5c",
  "max_answer_time": 20,
  "audio": "5c33111d12758809ff867931",
  "stem_type": "mix",
  "sub_questions": [{
    "option_type": "text",
    "correct_option": [3],
    "question_texts": [""],
    "options": [{
      "option_index": 1,
      "option_text": "lean",
      "option_image": ""
    }, {
      "option_index": 2,
      "option_text": "less",
      "option_image": ""
    }, {
      "option_index": 3,
      "option_text": "lesson",
      "option_image": ""
    }]
  }],
。。。

想要通过子字段sub_questions的options的option_text之类的嵌套字段去搜索

写成：

sub_questions.options.option_text

即可。

支持正则查询

举例：

MongoDB Compass

举例：搜索AD开头的lexile

MongoDB Compass中，想要用正则搜索字段：

grading
    lexile: "AD450L"

写法是：

{"grading.lexile": {$regex: "AD.*"}}

或：regex加上行首和行尾判断：

{"grading.lexile": {$regex: "^AD.*$"}}

或 regex用引号引起来

{"grading.lexile": {"$regex": "AD.*"}}

注：

另外试了试：

{"grading.lexile": {$regex: "^AD\d+.*$"}}

发现搜索不到，所以结论是：此处正则搜索不支持\d数字

举例：用正则语法去搜索title

{"title": {"$regex": "Chicka Chicka .*"}}

可以搜到匹配的多个数据：

举例：多个字段同时正则搜索+嵌套搜索+列表字段搜索

此处去实现一个更加复杂的：

正则搜索

多个条件组合搜索

字段嵌套搜索

列表字段搜索

要搜索的内容：

{
    "_id": "5c1777e1cc6df4563adf4b3c",
    "audio": "http://10.108.133.251:34800/audio/5c33111e12758809ff867a5e/238.mp3",
    "audio_length": 29,
    "audio_text": "f: Hi. I’m Tania. What’s your name? m: Hello. My name’s Jing. f: Nice to meet you, Jing. What class are you in? m: I’m in class 1B. And you? f: Me too. I’m in Class 1B too. m: Who’s our teacher? f: Mr Smith. m: And where’s our classroom? f: This way. Come with me. m: OK. Great.",
    "ave_answer_time": 70,
    "checkpoint": [
        73,
        83,
        "对话和应答"
    ],
    "difficulty": 3.2,
    "major_type": "单选多题",
    "max_answer_time": 140,
    "question_number": 238,
    "stem_image": "http://10.108.133.251:34800/image/5c32f6b012758802476f7f9d/school.png",
    "stem_text": "",
    "stem_type": "mix",
    "sub_questions": [
        {
            "correct_option": [
                1
            ],
            "option_type": "text",
            "options": [
                {
                    "option_image": "",
                    "option_index": 1,
                    "option_text": "Yes"
                },
                {
                    "option_image": "",
                    "option_index": 2,
                    "option_text": "No"
                }
            ],
            "question_texts": [
                "Jing and Tania are in the same class."
            ]
        },
        {
            "correct_option": [
                1
            ],
            "option_type": "text",
            "options": [
                {
                    "option_image": "",
                    "option_index": 1,
                    "option_text": "Yes"
                },
                {
                    "option_image": "",
                    "option_index": 2,
                    "option_text": "No"
                }
            ],
            "question_texts": [
                "Their teacher is a man."
            ]
        },
        {
            "correct_option": [
                2
            ],
            "option_type": "text",
            "options": [
                {
                    "option_image": "",
                    "option_index": 1,
                    "option_text": "Yes"
                },
                {
                    "option_image": "",
                    "option_index": 2,
                    "option_text": "No"
                }
            ],
            "question_texts": [
                "Jing knows where the classroom is."
            ]
        }
    ]
},

想要搜索字段：

stem_text

audio_text

sub_questions的question_texts（这个列表）中的任何一个

sub_questions的options（这个列表中的）任何一个的option_text

包含了teacher的话

则搜索条件可以写成：

{
  '$or': [{
      'stem_text': {
        '$regex': 'teacher',
        '$options': 'im'
      }
    },
    {
      'audio_text': {
        '$regex': 'teacher',
        '$options': 'im'
      }
    },
    {
      'sub_questions.question_texts': {
        '$regex': 'teacher',
        '$options': 'im'
      }
    },
    {
      'sub_questions.options.option_text': {
        '$regex': 'teacher',
        '$options': 'im'
      }
    }
  ]
}

对应代码：

          findParam["$or"] = [
              {"stem_text": {"$regex": searchText, "$options": "im"}},
              {"audio_text": {"$regex": searchText, "$options": "im"}},
              {"sub_questions.question_texts": {"$regex": searchText, "$options": "im"}},
              {"sub_questions.options.option_text": {"$regex": searchText, "$options": "im"}},
          ]

相关部分完整代码：

      findParam = {}

      searchText = parsedArgs["searchText"]
      if searchText:
          findParam["$or"] = [
              {"stem_text": {"$regex": searchText, "$options": "im"}},
              {"audio_text": {"$regex": searchText, "$options": "im"}},
              {"sub_questions.question_texts": {"$regex": searchText, "$options": "im"}},
              {"sub_questions.options.option_text": {"$regex": searchText, "$options": "im"}},
          ]

      majorType = parsedArgs["majorType"]
      if majorType:
          findParam["major_type"] = majorType

      sortBy = "question_number"
      log.debug("findParam=%s", findParam)
      sortedQuestionsCursor = questionCollection.find(findParam).sort(sortBy, pymongo.ASCENDING)
      totalCount = sortedQuestionsCursor.count()

即可搜索到要的内容：

举例：搜索题干类型题目中包含teach的题目

举例另一个复杂的例子：

代码：

findParam = {}

majorType = parsedArgs["majorType"]
if majorType:
    findParam["major_type"] = majorType

stemType = parsedArgs["stemType"]
if stemType:
    findParam["stem_type"] = stemType

checkpointList = parsedArgs["checkpointList"]
if checkpointList:
    checkpointList = checkpointList.split(",")
    checkpointOrParamList = []
    for eachCheckpoint in checkpointList:
        curCheckpointRegex = {"checkpoint": {"$regex": eachCheckpoint, "$options": "im"}}
        checkpointOrParamList.append(curCheckpointRegex)
    checkpointAndParamList = [ { "$or": checkpointOrParamList} ]
    if "$and" in findParam:
        findParam["$and"].extend(checkpointAndParamList)
    else:
        findParam["$and"] = checkpointAndParamList

searchText = parsedArgs["searchText"]
if searchText:
    searchTextOrParamList = [
        {"stem_text": {"$regex": searchText, "$options": "im"}},
        {"audio_text": {"$regex": searchText, "$options": "im"}},
        # {"sub_questions.option_type": "text"},
        {"sub_questions.question_texts": {"$regex": searchText, "$options": "im"}},
        {"sub_questions.options.option_text": {"$regex": searchText, "$options": "im"}},
        # {"sub_questions.options.option_image": {"$regex": searchText, "$options": "im"}},
    ]

    searchTextAndParamList = [{ "$or": searchTextOrParamList}]
    if "$and" in findParam:
        findParam["$and"].extend(searchTextAndParamList)
    else:
        findParam["$and"] = searchTextAndParamList

sortBy = "question_number"
log.debug("findParam=%s", findParam)
sortedQuestionsCursor = questionCollection.find(findParam).sort(sortBy, pymongo.ASCENDING)

生成的相关搜索条写法是：

{
  'major_type': '单选多题',
  'stem_type': 'mix',
  '$and': [{
    '$or': [{
      'checkpoint': {
        '$regex': '对话',
        '$options': 'im'
      }
    }, {
      'checkpoint': {
        '$regex': '理解',
        '$options': 'im'
      }
    }]
  }, {
    '$or': [{
      'stem_text': {
        '$regex': 'teacher',
        '$options': 'im'
      }
    }, {
      'audio_text': {
        '$regex': 'teacher',
        '$options': 'im'
      }
    }, {
      'sub_questions.question_texts': {
        '$regex': 'teacher',
        '$options': 'im'
      }
    }, {
      'sub_questions.options.option_text': {
        '$regex': 'teacher',
        '$options': 'im'
      }
    }]
  }]
}

即可查到需要的内容。

对搜索结果排序

对于搜索出的结果，想要针对某个或某些键去排序，则：

总体逻辑

给sort传入key和排序方向

排序方向值

顺序：1

倒序：-1

Python的API代码

语法：

collection.find(xxx).sort("key", pymongo.ASCENDING)

举例：不区分大小写找包含sleep的文件名

findFileCursor = fsCollection2.find({"filename": {"$regex": "sleep", "$options": "i"}})

举例：搜索结果根据question_number排序

举例：

      sortBy = "question_number"
      sortedQuestionsCursor = questionCollection.find(findParam).sort(sortBy, pymongo.ASCENDING)

工具

MongoDB shell或其他GUI工具（比如Robot 3T）中是：

collection.find(xxx).sort({"key": 1})

举例：

db.collection.find().sort( { age: 1 } )

crifan.com，使用署名4.0国际(CC BY 4.0)协议发布 all right reserved，powered by Gitbook最后更新： 2020-05-25 18:34:07

GridFS存储文件

GridFS存储文件

MongoDB针对于文件，尤其是大文件，专门设计了一套接口，叫做：GridFS

此处总结一下GridFS的使用心得。

TODO：

如何基于Flask搭建一个文件下载服务，甚至可以支持断点续传功能。把之前相关代码贴过来。

把更多帖子内容整理至此

GridFS

【已解决】GridFS保存文件时如何得到文件的id或_id

【已解决】用Python去连接本地mongoDB去用GridFS保存文件

【已解决】MongoDB的GridFS中基于文件名或id去下载文件

【已解决】MongoDB的GridFS中只返回file的chunks的个数而不返回chunks.data

【基本解决】Python中把wma、wav等格式音频转换为mp3

【未解决】Mongo中更新gridfs中的mp3文件的metadata信息且尽量保持id不变

【已解决】远程的mongoDB中GridFS报错：AttributeError GridFS object has no attribute totalSize

【规避解决】Flask-PyMongo中如何查询gridfs中的文件

【已解决】如何用PyMongo中的GridFS的put去保存添加文件

【已解决】PyMongo中GridFS的exists始终检测不到文件已存在

【已解决】Flask中Mongo的GridFS数据如何保存为绝对路径的下载文件地址

【已解决】MongoDB通过GridFS的API的put保存文件时添加额外信息

【已解决】PyMongo的GridFS中使用fs的collection去put出错：TypeError Collection object is not callable

【已解决】把本地mp3文件存入在线Mongo中且填写meta信息

【已解决】Flask中连接远程MongoDB数据库的gridfs并返回查询到的文件数据

和其中mongofiles相关的：

【已解决】用mongofiles去删除GridFS中的文件

【无法也无须解决】用mongofiles给GridFS中添加文件时添加额外参数属性字段

【已解决】mongofiles中put保存和get下载获取时指定文件名

一些供参考的资料：

GirdFS官网文档

GridFS — MongoDB Manual 3.6

Pymongo

GridFS的例子

GridFS Example — PyMongo 3.6.1 documentation

GridFS的API

gridfs – Tools for working with GridFS — PyMongo 3.6.1 documentation

相关的grid_file

grid_file – Tools for representing files stored in GridFS — PyMongo 3.6.1 documentation

一些GirdFS的心得

通过id查找gridfs中file文件

注意不是：

> db.fs.files.find({"id": "5b556ee47f4d38ba6a189222"})
> db.fs.files.find({"_id": "5b556ee47f4d38ba6a189222"})

而是ObjectId("5b556ee47f4d38ba6a189222")：

> db.fs.files.find({"_id": ObjectId("5b556ee47f4d38ba6a189222")})
{ "_id" : ObjectId("5b556ee47f4d38ba6a189222"), "contentType" : "audio/mpeg", "chunkSize" : 261120, "metadata" : { "song" : { "singers" : [ "ChuChu TV" ] }, "series" : { "number" : 0, "name" : "" }, "topics" : [ ], "storybook" : { "publisher" : "", "isFiction" : "未知", "lexileIndex" : "", "awards" : "", "authors" : [ ], "foreignCountry" : "" }, "keywords" : { "fromName" : [ "Finger", "Family" ], "other" : [ ], "fromContent" : [ "Daddy Finger" ] }, "name" : "Finger Family", "resourceType" : "song", "mainActors" : [ ], "contentAbstract" : "", "isSeries" : false, "fitAgeStart" : 3, "fitAgeEnd" : 6, "fileInfo" : { "isAudio" : true, "contentType" : "audio/mpeg", "name" : "Finger Family.mp3", "suffix" : "mp3" } }, "filename" : "Finger Family.mp3", "length" : 2604280, "uploadDate" : ISODate("2018-07-23T06:00:04.925Z"), "md5" : "946564effc4c0a835c55564377e7d819" }
>

删除文件

举例：

> db.fs.files.deleteOne({"_id": ObjectId("5b556ee47f4d38ba6a189222")})
{ "acknowledged" : true, "deletedCount" : 1 }

格式化带缩进美观的输出结果

后面加上：.pretty()

> db.fs.files.find({"_id": ObjectId("5b556ee47f4d38ba6a189222")}).pretty()
{
    "_id" : ObjectId("5b556ee47f4d38ba6a189222"),
    "contentType" : "audio/mpeg",
    "chunkSize" : 261120,
    "metadata" : {
        "song" : {
            "singers" : [
                "ChuChu TV"
            ]
        },
        "series" : {
            "number" : 0,
            "name" : ""
        },
        "topics" : [ ],
        "storybook" : {
            "publisher" : "",
            "isFiction" : "未知",
            "lexileIndex" : "",
            "awards" : "",
            "authors" : [ ],
            "foreignCountry" : ""
        },
        "keywords" : {
            "fromName" : [
                "Finger",
                "Family"
            ],
            "other" : [ ],
            "fromContent" : [
                "Daddy Finger"
            ]
        },
        "name" : "Finger Family",
        "resourceType" : "song",
        "mainActors" : [ ],
        "contentAbstract" : "",
        "isSeries" : false,
        "fitAgeStart" : 3,
        "fitAgeEnd" : 6,
        "fileInfo" : {
            "isAudio" : true,
            "contentType" : "audio/mpeg",
            "name" : "Finger Family.mp3",
            "suffix" : "mp3"
        }
    },
    "filename" : "Finger Family.mp3",
    "length" : 2604280,
    "uploadDate" : ISODate("2018-07-23T06:00:04.925Z"),
    "md5" : "946564effc4c0a835c55564377e7d819"
}
>

crifan.com，使用署名4.0国际(CC BY 4.0)协议发布 all right reserved，powered by Gitbook最后更新： 2020-05-26 21:38:33

查看当前MongoDB信息

查看当前MongoDB信息

想要查看当前MongoDB信息，即如何得知mongod的 启动文件、 配置文件、log日志文件、数据文件路径等等是什么

经过研究，可以用如下方法：

可以通过：

systemctl status mongod

中看到启动文件，比如：

[root@xxx-general-01 ~]# systemctl status mongod
[0m mongod.service - SYSV: Mongo is a scalable, document-oriented database.
   Loaded: loaded (/etc/rc.d/init.d/mongod; bad; vendor preset: disabled)
   Active: active (running) since Tue 2018-04-10 15:37:29 CST; 20h ago
     Docs: man:systemd-sysv-generator(8)
   CGroup: /system.slice/mongod.service
           1096 /usr/bin/mongod -f /etc/mongod.conf

Apr 10 15:37:28 xxx-general-01 systemd[1]: Starting SYSV: Mongo is a scalable, document-oriented database....
Apr 10 15:37:28 xxx-general-01 runuser[1077]: pam_unix(runuser:session): session opened for user mongod by (uid=0)
Apr 10 15:37:29 xxx-general-01 runuser[1077]: pam_unix(runuser:session): session closed for user mongod
Apr 10 15:37:29 xxx-general-01 mongod[1058]: Starting mongod: [  OK  ]
Apr 10 15:37:29 xxx-general-01 systemd[1]: Started SYSV: Mongo is a scalable, document-oriented database..

中的：

/etc/rc.d/init.d/mongod

是启动脚本

然后再去查看此启动脚本的内容，可以找到配置文件：

[root@xxx-general-01 ~]# cat /etc/rc.d/init.d/mongod
#!/bin/bash

# mongod - Startup script for mongod

# chkconfig: 35 85 15
# description: Mongo is a scalable, document-oriented database.
# processname: mongod
# config: /etc/mongod.conf

. /etc/rc.d/init.d/functions

# NOTE: if you change any OPTIONS here, you get what you pay for:
# this script assumes all options are in the config file.
CONFIGFILE="/etc/mongod.conf"
OPTIONS=" -f $CONFIGFILE"

mongod=${MONGOD-/usr/bin/mongod}

MONGO_USER=mongod
MONGO_GROUP=mongod
...

中的：

/etc/mongod.conf

然后再从配置文件中看到，对应的log日志，数据文件等信息：

[root@xxx-general-01 ~]# cat /etc/mongod.conf
# mongod.conf

# for documentation of all options, see:
#   http://docs.mongodb.org/manual/reference/configuration-options/

# where to write logging data.
systemLog:
  destination: file
  logAppend: true
  path: /var/log/mongodb/mongod.log

# Where and how to store data.
storage:
  dbPath: /var/lib/mongo
  journal:
    enabled: true
#  engine:
#  mmapv1:
#  wiredTiger:

# how the process runs
processManagement:
  fork: true  # fork and run in background
  pidFilePath: /var/run/mongodb/mongod.pid  # location of pidfile

# network interfaces
net:
  port: 32018
  bindIp: 127.0.0.1,172.16.141.197 # Listen to specific IP
#  bindIp: 127.0.0.1  # Listen to local interface only, comment to listen on all interfaces.
#  bindIp: 0.0.0.0  # Listen to all interfaces
#  port: 27017

security:
  authorization: 'enabled'

#operationProfiling:

#replication:

#sharding:

## Enterprise-Only Options

#auditLog:

#snmp:

中，找到：

日志文件：/var/log/mongodb/mongod.log

数据文件（路径）：/var/lib/mongo

从当前运行的MongoDB找到conf配置路径

前提：当前mongodb（服务端mongod）正在运行

目的：想要找到系统中MongoDB的配置文件所在位置

配置文件一般是mongod.conf

解决方案

通过查看进程详情中可以看到conf配置文件路径

举例

crifanli@crifanlideMac  /  ps aux | grep mongod
crifanli          8712   0.0  0.0  4258648    208 s000  R+    1:10上午   0:00.00 grep --color=auto --exclude-dir=.bzr --exclude-dir=CVS --exclude-dir=.git --exclude-dir=.hg --exclude-dir=.svn --exclude-dir=.idea --exclude-dir=.tox mongod
crifanli          8676   0.0  1.3  5524376  40376   ??  S     1:05上午   0:01.89 /usr/local/opt/mongodb-community/bin/mongod --config /usr/local/etc/mongod.conf

对应的是：

/usr/local/etc/mongod.conf

crifan.com，使用署名4.0国际(CC BY 4.0)协议发布 all right reserved，powered by Gitbook最后更新： 2020-07-11 08:54:25

连接远程MongoDB的方式

连接远程MongoDB的方式

背景：

在远程阿里云ECS服务器中有个MongoDB数据库：

IP：47.96.131.109

Port：32018

其中有个：

gridfs数据库

用户名：gridfs

角色：dbOwner

且服务端mongod正在运行了

下面是如何去连接该远程的mongo数据库几种方式：

服务器中本地连接

服务器上本地客户端：mongo shell

[root@xxx-general-01 ~]# mongo --port 32018
MongoDB shell version: 3.2.19
connecting to: 127.0.0.1:32018/test

进去后再：

use gridfs
db.auth("gridfs", "password")

或者直接：

mongo gridfs --port 32018 -u gridfs -p password --authenticationDatabase gridfs

Mac本地连接远端MongoDB

Mac中本地mongo shell去连接远程MongoDB

以gridfs用户去登录

以用户gridfs去登录，且（限定了）只（能）访问数据库gridfs：

mongo 47.96.131.109:32018/gridfs  -u gridfs -p password --authenticationDatabase gridfs

或：

mongo gridfs --host 47.96.131.109 --port 32018  -u gridfs -p password --authenticationDatabase gridfs

以admin用户去登录

以用户admin去登录，没有限定访问哪个数据库（后续则可以访问其他数据，前提是admin本身有这个权限）：

mongo --host 47.96.131.109 --port 32018 -u root -p pwd --authenticationDatabase admin

Python的pymongo代码连接远程MongoDB

import pymongo
from pymongo import MongoClient
import gridfs

# from pymongo.objectid import ObjectId
# from pymongo import objectid
from bson.objectid import ObjectId

from gridfs import GridFS

MongoHost = "47.96.131.109"
MongoPort = 32018

MongoUseAuth = True
# MongoUseAuth = False

# with auth
MongoUsername = "gridfs"
MongoPassword = “password"
MongoAuthenticationDatabase = "gridfs"

mongodbUri = ""
if MongoUseAuth :
    mongodbUri = "mongodb://%s:%s@%s:%s/%s" % (
        quote_plus(MongoUsername), \
        quote_plus(MongoPassword), \
        MongoHost, \
        MongoPort, \
        MongoAuthenticationDatabase \
    )
    #'mongodb://gridfs:password@47.96.131.109:32018/gridfs'
else:
    mongodbUri = "mongodb://%s:%s" % (
        MongoHost, \
        MongoPort
    )
    #'mongodb://localhost:32018'
    #'mongodb://47.96.131.109:32018’

mongoClient = MongoClient(mongodbUri)
gridfsDb = mongoClient.gridfs
fsCollection = GridFS(gridfsDb)

PyCharm中mongo4idea中的连接远端MongoDB

配置参数：

General

截图：

文字：

Server url(s)：47.96.131.109:32018

User Database：gridfs

Authentication

截图：

文字：

Username：gridfs

Password：your_password

Auth. database：gridfs

Auth. mechanism：SCRAM-SHA-1

即可成功连接：

crifan.com，使用署名4.0国际(CC BY 4.0)协议发布 all right reserved，powered by Gitbook最后更新： 2020-07-28 18:15:23

坑

坑

此处整理一些常见的MongoDB的坑及解决办法。

crifan.com，使用署名4.0国际(CC BY 4.0)协议发布 all right reserved，powered by Gitbook最后更新： 2020-05-23 11:43:23

停止MongoDB

停止MongoDB

想要去停止MongoDB的服务端。

对于之前是正常安装方式

brew install mongodb-community

则去停止运行方式是

brew services stop mongodb-community

不过之前遇到过特殊情况，试了各种方式都无法直接关闭掉，经研究最后是用：

sudo mongod -f /etc/mongod.conf --shutdown

输出：

killing process with pid: 30213

才算真正的关闭了MongoDB。

详见：

【已解决】CentOS中如何彻底真正关闭mongod的服务

crifan.com，使用署名4.0国际(CC BY 4.0)协议发布 all right reserved，powered by Gitbook最后更新： 2020-05-23 11:45:10

Cursor not found

Cursor not found

用pymongo期间可能会报错：

pymongo.errors.CursorNotFound: Cursor not found

原因：

此处的：

for eachDialog in dialogCollection.find():

find会返回多个数据，而这些数据的处理时间，超过了默认最长时间10分钟，所以超时报错了。

解决办法：

去掉超时时间的设置，加上参数no_cursor_timeout=True

代码改为：

# for eachDialog in dialogCollection.find():
cursor = dialogCollection.find(no_cursor_timeout=True)
for eachDialog in cursor:
    yield eachDialog
cursor.close()

即可。

crifan.com，使用署名4.0国际(CC BY 4.0)协议发布 all right reserved，powered by Gitbook最后更新： 2020-05-23 20:32:25

参数_id是不是字符串

参数_id是ObjectId对象而不是字符串

直接说具体的坑是：Pymongo中的很多函数，比如exists等，传入的参数id是ObjectId对象而不是id的字符串

发现并解决坑的具体过程：

此处，gridfs的官网文档：

gridfs – Tools for working with GridFS — PyMongo 3.6.1 documentation

exists(document_or_id=None, session=None, **kwargs)

函数来说，没有说明document_or_id是个特殊的ObjectId的这个类的实例，而其例子：

>>> fs.exists(file_id)
>>> fs.exists({"_id":file_id})
>>> fs.exists(_id=file_id)
>>> fs.exists({"filename": "mike.txt"})
>>> fs.exists(filename="mike.txt")

很容易让人误解就是普通的_id的值的字符串，比如：

"5abc96dfa4bc715f473f0297"

或

"ObjectId('5abc96dfa4bc715f473f0297')"

搞得尝试半天也无法正常执行，找不到本来已存在的文件。

幸亏：

django - Querying by "_id" doesn't return file in MongoDB in Python, using PyMongo - Stack Overflow

中解释的，对于pymongo

2.2版本之前：

from pymongo.objectid import ObjectId

2.2版本之后：

from bson.objectid import ObjectId

然后才能用于exists：

fileIdToDelete = '5abc8d77a4bc71563222d455'
fileObjectIdToDelete = ObjectId(fileIdToDelete)
if fsCollection.exists(fileObjectIdToDelete):
    fsCollection.delete(fileObjectIdToDelete)

并且注意到作者是2012年，6年前就回复了该答案，结果此处pymongo在6年后，都没有及时更新此内容，真是醉了。

希望mongodb的文档以后能及时更新啊。

crifan.com，使用署名4.0国际(CC BY 4.0)协议发布 all right reserved，powered by Gitbook最后更新： 2020-05-28 10:26:49

不要在admin中创建普通用户

不要在admin中创建普通用户

创建用户时注意不要在admin数据库中创建：

如果不小心是在最开始的admin中去用db.createUser新建的普通用户，则实际上新建的用户只是属于admin数据库的。

可以用admin账号登录后，通过如下命令看到：

> use admin
switched to db admin
> show users
{
        "_id" : "admin.root",
        "user" : "root",
        "db" : "admin",
        "roles" : [
                {
                        "role" : "root",
                        "db" : "admin"
                }
        ]
}
{
        "_id" : "admin.log",
        "user" : "log",
        "db" : "admin",
        "roles" : [
                {
                        "role" : "dbOwner",
                        "db" : "log"
                }
        ]
}

所以要切换到对应新数据库中，再去创建才可以。

否则就会导致后续没有权限操作其下数据。

crifan.com，使用署名4.0国际(CC BY 4.0)协议发布 all right reserved，powered by Gitbook最后更新： 2020-05-28 10:25:30

附录

附录

下面列出相关参考资料。

crifan.com，使用署名4.0国际(CC BY 4.0)协议发布 all right reserved，powered by Gitbook最后更新： 2020-05-22 20:24:17

教程和文档

教程和文档

此处整理一些关于MongoDB的官方和非官网的各种有用资料，供需要时查询和参考。

MongoDB官网资料

官方文档入口：

The MongoDB 4.0 Manual — MongoDB Manual

官网还有个系列教程：

MongoDB University

部分细节内容：

更新数据

db.collection.update() — MongoDB Manual

查询

Query Documents — MongoDB Manual

Query on Embedded/Nested Documents — MongoDB Manual

Query an Array — MongoDB Manual

Query an Array of Embedded Documents — MongoDB Manual

查询期间条件组合

$or — MongoDB Manual

Read Data using Operators and Compound Queries

正则搜索

$regex

列表查询

Array Query Operators — MongoDB Manual

聚合

Aggregation — MongoDB Manual 3.4

Driver的

MongoDB Drivers and Client Libraries — MongoDB Manual 3.6

用户和权限认证

Authentication

Authentication — MongoDB Manual 3.6

authenticate — MongoDB Manual 3.6

Users

Users — MongoDB Manual 3.6

权限

RBAC

Role-Based Access Control — MongoDB Manual 3.6

角色

Built-In Roles — MongoDB Manual 3.6

User-Defined Roles — MongoDB Manual 3.6

grantRolesToUser — MongoDB Manual 3.6

Resource

Resource Document — MongoDB Manual 3.6

新建用户

createUser — MongoDB Manual 3.6

第三方资料

官网的（部分完成的）中文翻译：

mongoing.com

MongoDB 4.2 手册

Documentation | MongoDB中文社区

MongoDB 3.4 手册

安装MongoDB — MongoDB Manual 3.4

极客学院

mongodb 数据库 (1) - 《从零开始学 Python》(第二版) - 极客学院Wiki

Mongo Shell资料

Mongo Shell的资料：

英文

mongo Shell Quick Reference — MongoDB Manual 3.6

中文

mongo shell — MongoDB Manual 3.4

注：翻译未必是完整的，且不一定是最新版本

crifan.com，使用署名4.0国际(CC BY 4.0)协议发布 all right reserved，powered by Gitbook最后更新： 2020-05-28 09:24:46

参考资料

参考资料

【已解决】MongoDB版本区别：Community vs Enterprise

【记录】mac搭建开发环境：安装最新版MongoDB

【已解决】Python的Flask中pymysql中mysql返回分页查询结果

【已解决】Pymongo中新增插入记录

【已解决】Python的pymongo中根据指定字段的时间范围去查询数据且排序

【或许解决】Python的Pymongo中gridfs文件去更新保存metadata信息

【已解决】mongoimport/mongoexport和mongodump/mongorestore的区别

【已解决】从MongoDB数据库中导出数据

【已解决】把json数据恢复导入到本地MongoDB数据库的某个集合中

【已解决】重新将本地MongoDB数据storybook导入到在线环境

【记录】把在线的dev的MongoDB备份后恢复到本地

【已解决】PySpider项目迁移到别的电脑重新继续运行

【已解决】确认服务器是否已经正在运行MongoDB的服务mongod

【已解决】去更新绘本查询中的MongoDB中的绘本的title字段数据

【已解决】MongoDB中更新现有记录新插入字段

【已解决】Mongo的shell中新建一个空的db数据库和collection集合

【已解决】Python的MongoDB的Pymongo中实现嵌套字段即子字段的搜索

【已解决】Python的MongoDB的Pymongo中实现list列表中的内容的搜索

【已解决】Python的MongoDB的Pymongo中实现多个正则条件的组合搜索

【已解决】Python的MongoDB的pymongo中搜索查询支持regex正则和多个条件组合和字段嵌套和列表字段

【已解决】Python的MongoDB的Pymongo中搜索列表字段中是否包含某个列表值中任何一个以及正则匹配部分内容

【已解决】Win中Robot 3T访问VMWare中macOS中MongoDB报错：Network is unreachable Reason couldn't connect to server connection attempt failed SocketException

【已解决】Win中尝试用Robot 3T连接和操作VMWare中macOS中MongoDB

【已解决】Mongo中让搜索支持不区分大小写

【已解决】Pymongo出错：pymongo.errors.OperationFailure: Authentication failed

【已解决】MongoDB的MongoDB Compass中用正则进行模糊匹配字段

【规避解决】Flask-PyMongo中如何查询gridfs中的文件 – 在路上

【已解决】python中mongo出错：pymongo.errors.CursorNotFound: Cursor not found

【记录】MongoDB中本地写代码实现数据合并和迁移

【已解决】在线CentOS中Flask运行mongo出错：pymongo.errors.ServerSelectionTimeoutError localhost Errno 111 Connection refused

【已解决】添加了IP限制的mongod重启出错：Job for mongod.service failed because the control process exited with error code

【已解决】mongo中给bindIp添加多个IP后出错：getaddrinfo failed Name or service not known

【已解决】mongo启动失败：connection /var/lib/mongo/WiredTiger.turtle handle-open open Permission denied

【已解决】mongo启动失败：Failed to unlink socket file /tmp/mongodb-xxx.sock errno 1 Operation not permitted

【已解决】添加了IP限制的mongod重启出错：Job for mongod.service failed because the control process exited with error code – 在路上

【已解决】mongo启动失败：connection /var/lib/mongo/WiredTiger.turtle handle-open open Permission denied

【已解决】配置mongod以允许内网其他服务器访问mongo服务

【无法解决】尝试用mongo的bindIp去实现限制特定IP才能连接mongo服务

【未解决】systemctl或service无法重启或启动mongod的服务mongod

【已解决】mongo中给bindIp添加多个IP后出错：getaddrinfo failed Name or service not known

【已解决】mongo启动失败：Failed to unlink socket file /tmp/mongodb-xxx.sock errno 1 Operation not permitted

【已解决】给MongoDB数据库新建用户和权限

【已解决】pymongo中用MongoClient去连接远程加了权限控制的mongoDB

【已解决】本地mongo shell中连接远程加了权限控制的mongoDB

【已解决】如何允许外网IP远程访问MongoDB数据库

【已解决】连接远程mongoDB失败：Failed to connect to after 5000ms milliseconds giving up

【已解决】阿里云ECS服务器中已有的MongoDB的用户名密码和端口

【已解决】PyMongo中GridFS的exists始终检测不到文件已存在

【已解决】安装MongoDB Compass去图形化查看Mongo数据 – 在路上

How to Import .bson file format on mongodb - Stack Overflow

最佳的MongoDB客户端管理工具 - chszs的专栏 - CSDN博客

Working with MongoDB in Visual Studio Code

文档数据库_文档型数据库_AWS 数据库服务 - AWS 云服务

Top 12 NoSQL Document Databases in 2020 - Reviews, Features, Pricing, Comparison

常用数据库及nosql - 简书

Sql Or NoSql，看完这一篇你就懂了 - 五月的仓颉 - 博客园

NoSQL 还是 SQL ？这一篇讲清楚 - 掘金

常用数据库有哪些（附带数据库排名）？

MongoDB跑步进中国

MongoDB API

MongoDB Drivers and Ecosystem — MongoDB Drivers

VSCode支持MongoDB

MongoDB 常用的几大GUI工具 - 自由早晚乱余生 - 博客园

Mongodb 工具 Studio 3T 和 Robo 3T · 码农装备

Robo 3T | Free, open-source MongoDB GUI (formerly Robomongo)

MongoDB的可视化工具：Studio 3T和Robo 3T有什么区别啊？ - SegmentFault 思否

cursor.sort() — MongoDB Manual

$orderby — MongoDB Manual

MongoDB 排序 | 菜鸟教程

mongodb - How do you tell Mongo to sort a collection before limiting the results? - Stack Overflow

MongoDB find() Method: Introduction & Query Examples | Studio 3T

MongoDB Python Drivers — MongoDB Drivers

初尝node.js + Express + MongoDB + Vue.js 项目构建(2) - 个人文章 - SegmentFault

TODO 待整理

【已解决】mongo命令行中如何删除文件

【已解决】把本地的音频字幕等数据存储到远程服务器的MongoDB数据库中

【已解决】mongo中给普通数据库gridfs创建root的角色失败：Error couldn't add user No role named root@gridfs

【已解决】本地mongo shell中连接远程加了权限控制的mongoDB

【已解决】阿里云ECS服务器中已有的MongoDB的用户名密码和端口

【未解决】尝试用Mongo Management Studio去实现导入文件到Mongo的gridfs且带metadata信息

【已解决】确认服务器中MongoDB数据库是否有或已开启记录登录的日志

【已解决】确认服务器中MongoDB数据库是否有或已开启记录登录的日志

【已解决】MongoDB开启访问控制后currentOp出错：not authorized on admin to execute command

【已解决】给MongoDB数据库新建用户和权限

【已解决】修改MongoDB的默认端口号27017为别的端口

【已解决】mongo的shell中find返回多个有限个数的结果

【已解决】公司Wi-Fi更换运营商导致IP变化导致远程Mongo连不上

【已解决】连接远程mongoDB失败：Failed to connect to after 5000ms milliseconds giving up

【已解决】pymongo中用MongoClient去连接远程加了权限控制的mongoDB

【已解决】用PyCharm的MongoDB插件连接远程MongoDB数据库

【已解决】MongoDB的用户的密码中包含@如何写URI

【已解决】给MongoDB限制IP访问

【已解决】远程MongoDB新增dialog数据库并新增对应用户和权限

【已解决】PyCharm连接远程添加security的authorization的MongoDB出错：com.mongodb.MongoCommandExceptions: Command failed with error 13

【已解决】Flask-PyMongo出错：RuntimeError Working outside of application context

【已解决】pymongo的count()出错：pymongo.errors.ServerSelectionTimeoutError timed out

【记录】通过阿里云ECS服务器安全组限制访问mongo的IP和端口

【已解决】用PyCharm写Python的MongoDB代码并调试

【已解决】配置mongod以允许内网其他服务器访问mongo服务

【已解决】PyCharm中安装MongoDB的插件：mongo4idea

mongodump — MongoDB Database Tools

crifan.com，使用署名4.0国际(CC BY 4.0)协议发布 all right reserved，powered by Gitbook最后更新： 2021-09-09 09:07:56