MongoDB常见操作(备忘)

  • 删除数据库
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>")
  • ……
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值