- 删除数据库
use <dbName>
db.dropDatabase()
- 复制数据库
db.copyDatabase("srcDbName","destdbName")
- 跨网络环境复制数据库
首先需要下载安装MongoDB Database Tools(下载MongoDB时不自带,需要额外下载)
方案一:mongodump搭配mongorestore
1.登陆源服务器
2.mongodump -h <MongoDB地址(ip:port(,ip:port...))> -u <源数据库用户名> -p <源数据库密码> -d <源数据库名> -o <源服务器上储存数据文件的目标路径>
3.将dump文件传输到目标服务器
4.登陆目标服务器
5.mongorestore -h <MongoDB地址(ip:port(,ip:port...))> -u <目标数据库用户名> -p <目标数据库密码> -d <目标数据库名> <目标服务器上储存数据文件的路径>
ps:如果提示报错:error connecting to host: could not connect to server: connection() : auth error: sasl conversation error: unable to authenticate using mechanism "SCRAM-SHA-1": (AuthenticationFailed) Authentication failed.
在-u前面加上一句:--authenticationDatabase admin
方案二:mongoexport搭配mongoimport
- 跨数据库复制集合
use <srcDbName>
db.<srcClName>.find().forEach(function(d){
db.getSiblingDB("<destDbName>")["<destClName>"].insert(d);
})
- 删除集合
db.<clName>.drop()
- 连接查询
//假设有两个集合user和user_detail,user表的_id对应user_detail表的userId,下面查询name为hhh的全部信息
db.user.aggregate([{
$lookup: {
from: "user_detail",
localField: "_id",
foreignField: "userId",
as: "detail"
}
}, {
$match: {
"name": "hhh"
}
}])
//查询结果
{
"_id":ObjectId("xxx"),
"name":"hhh",
"detail":[{
"userId":ObjectId("xxx"),
"address":"xxxxx"
}]
}
- select * from A where A.f not in (select B.f from B);查询在A表但不在B表的记录
db.<cl_A>.aggregate([
{
$lookup:
{
from: "<cl_B>",
localField: "<cl_A.fieldName>",
foreignField: "<cl_B.fieldName>",
as: "A_join_B"
}
},
{
$match: { "A_join_B": [] } // 在A表但不在B表,则联表结果为空
},
{
$project: {
"A_join_B": 0,
}
}
])
- 多级聚合查询
//但这种方法查出来的staff是指定bg下的所有staff,并无法区分是哪个bu的staff,全混一块了,没有分级展示= =
db.bg.aggregate([
{
$match: {
"_id": ObjectId("xxx")
}
},
{
$lookup: {
from: "bu",
localField: "_id",
foreignField: "bgId",
as: "bg_bu"
}
},
{
$addFields: {
"buId": {
$map: {
input: "$bg_bu",
in: {
input: "$$this._id",
}
}
},
}
},
{
$lookup: {
from: "staff",
localField: "buId",
foreignField: "buId",
as: "bu_staff"
}
}
])
- 获取所有字段名
mr = db.runCommand({
"mapreduce" : "<clName>",
"map" : function() {
for (var key in this) { emit(key, null); }
},
"reduce" : function(key, stuff) { return null; },
"out": "<clName>" + "_keys"
})
db[mr.result].distinct("_id")
- 修改字段名
db.<clName>.update({}, {$rename:{"旧键名称":"新键名称"}}, false, true)
- 删除字段
db.<clName>.update({},{"$unset":{"<keyName>":""}},{multi:true})
- 更新某个字段
db.<clName>.update({查询条件},{$set:{"<字段名>":"<字段值>"}})
- 获取集合中指定字段的不重复值,并以数组的形式返回
db.<clName>.distinct("<fieldName>")
- 单字段去重
//查询内容
db.<clName>.distinct("<要去重的字段名>",<查询条件>)
//查询计数
db.<clName>.distinct("<要去重的字段名>",<查询条件>).length
- 多字段组合去重
//查询内容
db.<clName>.aggregate([{
$group:{
_id: {name: "$name", sex: "$sex"},
}
}])
//查询计数
db.<clName>.aggregate([{
$group:{
_id: {name: "$name", sex: "$sex"},
}
},{
$count:"cnt"
}])
- 或查询
//查询id为1或者name为hhh的记录
db.<clName>.find({$or:[{"name":"hhh"},{"id":1}]})
//查询id为1或2的记录
db.<clName>.find({"id":{$in:[1,2]}})
- restore数据库(对应mongodump命令)
mongorestore -h <MongoDB地址(ip:port(,ip:port...))> -u <生产数据库用户名> -p <生产数据库密码> -d <生产数据库名> <生产服务器上储存数据文件的路径>
- 数组追加
db.<clName>.update({<查询条件>},{$addToSet:{"<fieldName>":"<addElem>"}})
- 数组查询
假设有集合test:[{
"tags":["abc","def"],
"name":"hhh",
},{
"tags":["abc","def","ghi","jkl"],
"name":"ggg",
}]
查询tags精确匹配["abc","def"]的文档:
db.test.find({"tags":["abc","def"]})
返回[{
"tags":["abc","def"],
"name":"hhh",
}]
查询tags包含["abc","def"]的文档:
db.test.find({"tags":{$all:["abc","def"]}})
返回[{
"tags":["abc","def"],
"name":"hhh",
},{
"tags":["abc","def","ghi","jkl"],
"name":"ggg",
}]
查询tags包含"abc"的文档:
db.test.find({"tags":"abc"})
返回[{
"tags":["abc","def"],
"name":"hhh",
},{
"tags":["abc","def","ghi","jkl"],
"name":"ggg",
}]
查询tags包含「包含"g"的元素」的文档:
db.test.find({"tags":{$regex:"g"}})
返回[{
"tags":["abc","def","ghi","jkl"],
"name":"ggg",
}]
- 文档数组查询
假设有集合test:[{
"_id": ObjectId("60e2fe0f824c0000900053e2"),
"ip": "1",
"tags": [{
"k": "k1",
"v": "v1"
}, {
"v": "v2",
"k": "k2"
}, {
"k": "k3",
"v": "v3"
}]
}, {
"_id": ObjectId("60e2fe29824c0000900053e3"),
"ip": "2",
"tags": [{
"k": "k1",
"v": "v1"
}, {
"k": "k2",
"v": "v2"
}, {
"k": "k3",
"v": "v3"
}]
}]
(两个文档的区别:k2和v2的顺序)
Go代码一:
cur, err: = cl.Find(Ctx, bson.M{
"tags": bson.M{
"$all": bson.A{
bson.M{
"k": "k1",
"v": "v1",
},
bson.M{
"k": "k2",
"v": "v2",
},
},
},
})
查询结果一:
{"Ip":"2","Tags":[{"K":"k1","V":"v1"},{"K":"k2","V":"v2"},{"K":"k3","V":"v3"}]}
Go代码二:
cur, err: = cl.Find(Ctx, bson.M{
"tags": bson.M{
"$all": bson.A{
bson.M{
"$elemMatch": bson.M{
"k": "k1",
"v": "v1",
},
},
bson.M{
"$elemMatch": bson.M{
"k": "k2",
"v": "v2",
},
},
},
},
})
查询结果二:
{"Ip":"1","Tags":[{"K":"k1","V":"v1"},{"K":"k2","V":"v2"},{"K":"k3","V":"v3"}]}
{"Ip":"2","Tags":[{"K":"k1","V":"v1"},{"V":"v2","K":"k2"},{"K":"k3","V":"v3"}]}
两次查询的区别:一次认顺序一次不认顺序
理解:elemMatch是匹配元素,不是匹配整个文档,所以文档内的元素顺序不影响匹配结果
- 更新文档数组的部分文档
db.metric_config.update({
"_id": ObjectId("6386fcbad1209d41709dc263"),
model_type: {
$all: [{
$elemMatch: {
type: "LSTM"
}
}]
}
}, {
$set: {
"model_type.$.status": "succeeded" // $代表获取的下标
}
})
- 查询内嵌文档:通过点表示法来表示内嵌文档的键
假设有集合test:[{
"user":{
"id":1,
"name":"hhh",
}
}]
查询user name为hhh的文档:
db.find({"user.name":"hhh"})
- 查看索引
db.<clName>.getIndexes()
- 创建索引
为单个字段创建索引:
db.<clName>.ensureIndex({"<fieldName>":1(按索引升序排序)/-1(按索引降序排序))},{"name":<索引名>})
为多个字段创建复合(组合)索引:
db.<clName>.ensureIndex({"<fieldName1>":1/-1(,"<fieldName2>":1/-1)...},{"name":<索引名>})
为多个字段创建复合(组合)唯一索引:
db.<clName>.ensureIndex({"<fieldName1>":1/-1(,"<fieldName2>":1/-1)...},{"name":<索引名>},{unique:true})
- 删除索引
db.<clName>.dropIndex("<indexName>")
- ……