一、简介
MongoDB是一个基于分布式文件存储的数据库,由C++语言编写。
与关系型数据库之间的术语对比
二、安装
docker pull mongo:4.4
27017 是默认端口 docker run -itd --name mongo -p 27017:27017 mongo:4.4 --auth docker exec -it mongo /bin/bash 或者 docker exec -it mongo mongo admin 进入管理库 · 创建用户 db.createUser({"user":"ansel", "pwd":"zrh", "roles":[{"role":"root","db":"admin"}]}); · 登录 db.auth("ansel","zrh") 返回1 成功 0 失败
三、 数据库操作
use database; 如果没有向数据库插入数据,则不会持久化数据库 删除数据库 db.dropDatabase();
四、集合操作
show tables; show collections; 查看集合 db.createCollection("item") 创建集合 show tables; show collections;
五、集合管理
capped 布尔 true则创建固定集合,当达到最大值时,它会自动覆盖最早的文档。(当值为true时,必须指定size参数) autoinde 布尔 自动在——id字段创建索引,默认为true size 数值 为固定集合指定一个最大值(以字节计算) nax 数值 集合中包含文档的最大数量
1 db.createCollection("order",{"capped":true,"size":1000,"max":10}); 创建 2 db.order.stats(); 查看集合详情信息 3 db.order.drop(); 删除 4 show collections 查看集合名称5 db.order.insertMany([{"type":"1"},{"computer":"hello world"}]); 插入多条
六、文档操作
6 db.users.save([{"name":"wangwu"},{"name":"ally"}]); 和insert作用一样 7 db.order.find(); 查找 db.order.save({"_id":ObjectId("642c10b5001e638116e4e491"),"name":"hhhahahaha"}); 更新: 注意这里一定要在capped : false的前提下进行修改 8 db.users.update({},{"$set":{"name":"user01","age":101}}); 更新语句 默认只更新第一条符合条件的数据 9 db.users.update({},{"$set":{"name":"user01","age":101}},{"multi":true}); 改变多条匹配的数据 10 db.users.update({},{"$set":{"name":"user01","age":101}},false, true); 第一个false: upsert 匹配条件作更新 不匹配条件作新增 db.集合名.update({条件},{更新逻辑},{"multi":true|false, "upsert": true|false}) 10 自增长 db.users.update({},{"$inc":{"age":1}},false,true); 11 删除字段 db.users.update({},{"$unset":{"age":1}}); 12 某个数组类型的键添加一个数组元素,不过滤重复的数据,添加时键存在,要求键值类型必须是数组,键不存在,则创建数组类型的键db.users.update({},{"$push":{"hobby":["coding","study"]}}); 13 删除数组元素 1删除最后一个 -1删除数组第一个 db.users.update({},{"$pop":{"hobby":1}}); 13 删除数组特定元素 db.users.update({},{"$pull":{"hobby":"football"}}); 14 删除多个特定数组元素 db.users.update({},{"$pullAll":{"hobby":["football","eat"]}}); 15 更改字段名字
七、条件差序
1 默认查询第一个+ db.users.findOne(); 2 范围查询 db.users.find({"age":{"$gt":30}}); db.users.find({"age":{"$ne":30}}); 不等于 3 条件查询 db.users.find({ "$or":[ {"age":{"$gt":30}}, {"$and":[ {"name":"wangwu"} ]} ] }) 4 db.users.find({"age":{"$gt":20},"name":"wangwu"}); 相当于并且 5 db.users.find({"name":{"$in":["wangwu","zhangsan"]}}); [ $nin 表示不在] 6 正则表达式 db.users.find({"name":{"$regex":/^w.*/}}); 正则选项 i - 不区分大小写匹配大小写的情况 m - 多行查找 db.users.find({"name":{"$regex":/^w.*/,"$options":"im"}})
八、投影
find({查询条件},{投影}) 非id字段,其他字段不能取反查询, 比如name:1 , age: 0 报错 包含id字段,id必须为0,不能为1
九、分页和排序
db.item.find().sort({"name":1}); --> 正序排列 db.item.find().sort({"name":-1}); --> 降序排列 db.users.find().sort({"age":1}); ---> 根据年龄升序 db.users.find().sort({"name":1}).skip(2).limit(2); 分页
十、springdata整合mongodb
1.Dependency
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-mongodb</artifactId> </dependency>
2.YAML
#spring-data-mongodb 会准备mongotemplate 对象,提供远程操作 spring: data: mongodb: host: 192.168.221.128 #mongodb 主机地址 port: 27017 #端口号 database: test #数据库 username: ansel #用户名 password: zrh #密码 authentication-database: admin
3.Test
@Autowired private MongoTemplate mongoTemplate;
3.1 Test Insert
/** * 新增 * <T> T insert(T pojo) * 使用注解配置或默认映射机制 * <T> T insert(Collection<T> pojos, Class<T> clazz) * 批量新增 * <T> T insert(T pojo, String collectionName); * 使用注解配置(除@Document外)或默认映射,向指定的collectionName集合中新增数据 * */ @Test public void testInsert(){ Order o1 = new Order(); o1.setName("jack"); o1.setPayment(100); o1.setItems(Arrays.asList("Ipad 2022","iphone13")); System.out.println("新增前 ==>" + 01); Order insert = mongoTemplate.insert(o1); System.out.println("新增后 ==>" + insert); List<Order> orders = new ArrayList<>(); for (int i = 0; i < 5; i++) { Order o2 = new Order(); o2.setName("Tom"); o2.setPayment(123); o2.setItems(Arrays.asList("Ipad 202" + i,"iphone13")); orders.add(o2); } System.out.println("新增前 ==>" + orders); Collection<Order> insert1 = mongoTemplate.insert(orders, Order.class); System.out.println("新增后 ==>" + insert1); }
3.2 Test Update
/** * 修改 - 全量替换 | 覆盖 * 使用save方法 * save方法是用于保存数据的,如果数据不包含主键信息,则一定是新增 * 如果包含主键信息,则匹配检查,相同覆盖,不同新增 * 不能做批量覆盖 */ @Test public void testSave(){ Order order = new Order(); order.setId("643135ff61eafa31cf4acd79"); order.setName("Tim"); order.setPayment(101); order.setItems(Arrays.asList("HUA WEI MATEPRO","XIAOMI")); Order save = mongoTemplate.save(order); System.out.println("更新后数据:"+save); }
/** * 修改 - 表达式更新 * $set $inc $push * * updateFirst = db.collectionName.update({},{},{"multi":false}) * updateMulti = db.collectionName.update({},{},{"multi":true}) */ @Test public void testUpdate(){ Query query = Query.query( Criteria.where("name").is("jack")); // {"$set":{"title":"JackV2"}} Update update = Update.update("name", "JackV2"); UpdateResult updateResult = mongoTemplate.updateFirst(query, update, Order.class); System.out.println("更新后:"+updateResult); } System.out.println("=============="); //pi'liang'x Query multiQuery = new Query(); Criteria criteria = Criteria.where("name") .in("wangwu", "Tom"); multiQuery.addCriteria(criteria); Update multiUpdate = new Update(); multiUpdate.set("name", "BatchTom"); mongoTemplate.updateMulti(multiQuery,multiUpdate, Order.class);
3.3 Test delete
/** * 删除 - 主键删除 * remove(Object pojo) - 只使用pojo实体对象中的主键作为条件,删除数据 * 删除- 全部删除 * remove(Class clazz) - 直接删除类型对应的集合中的全部数据 * 删除 - 条件删除 * remove(Query query, Class clazz) */ @Test public void testDeleteById(){ // Order order = new Order(); // order.setId("643135ff61eafa31cf4acd7d"); // DeleteResult result = mongoTemplate.remove(order); System.out.println("================="); //条件删除 Query query = Query.query( Criteria.where("payment").gte(101).lt(102) ); DeleteResult result = mongoTemplate.remove(query,Order.class); System.out.println("wasAcknowledged" + result.wasAcknowledged()); }
3.4 Test find
@Test public void testFind(){ List<Order> orders = mongoTemplate.findAll(Order.class); printList(orders); System.out.println("=================="); List<Order> order = mongoTemplate.findAll(Order.class, "order"); printList(order); System.out.println("=================="); //查询单一对象 // <T> T findById(Object id, Class<T> clazz); // 无数据返回null Order order1 = mongoTemplate.findById("643135d45c28ca33c75a8326", Order.class); System.out.println(order1); System.out.println("=================="); //查询单一对象 条件查询 // new Query() --> 查询全部数据 --> 自然序列第一条 Order all = mongoTemplate.findOne(new Query(), Order.class); System.out.println("all" + all); System.out.println("================"); //条件查询 //等值查询 Query query = Query.query( Criteria.where("name").is("ansel") ); Order one = mongoTemplate.findOne(query, Order.class); System.out.println("等值查询" + one); //不等值查询1 Query query2 = Query.query( Criteria.where("name").in("ansel") // nin 表示不存在 ); Order one1 = mongoTemplate.findOne(query2, Order.class); System.out.println("不等值查询1" + one1); //不等值查询2 Query query3 = Query.query( Criteria.where("name").ne("ansel") ); Order one3 = mongoTemplate.findOne(query3, Order.class); System.out.println("不等值查询2" + one3); //exist Query existQuery = Query.query( Criteria.where("payment").exists(true) ); //正则 Query regexQuery = Query.query( //db.order.find({"name":/^a/}); (在mongo客户端中 // 标记内容的开始和结束) //java 控制不要加斜线来标记范围 Criteria.where("name").regex("^a") ); Order one4 = mongoTemplate.findOne(regexQuery, Order.class); System.out.println("regex" + one4); System.out.println("==============="); //去重查询 findDistinct(Query query, String fieldName, // Class projectClass, Class<T> resultClass) //fieldName 投影字段名 //projectClass - 访问的集合对应的实体类型 //fieldClass 投影字段类型 Query distinctQuery = new Query(); List<String> distinctName = mongoTemplate. findDistinct(distinctQuery, "name", Order.class, String.class); distinctName.stream().forEach(System.out::println); System.out.println("=============="); //混合条件 一个字段有多个条件 满足其一即可 但是如果是数字范围 需全部满足 Query multiCircum = Query.query( //db.order.find({"name":/^a/}); (在mongo客户端中 // 标记内容的开始和结束) //java 控制不要加斜线来标记范围 Criteria.where("name").is("Jack").regex("2$") ); List<Order> results = mongoTemplate.find(multiCircum, Order.class); results.stream().forEach(System.out::println); System.out.println("==============="); //AND条件: 多个字段不同 用andOperations Query differentColQuery = Query.query( new Criteria().andOperator( Criteria.where("name").is("ansel"), Criteria.where("payment").gte(9999).lt(20000) ) ); List<Order> results2 = mongoTemplate.find(differentColQuery, Order.class); printList(results2); System.out.println("================="); //OR条件 Query differentColQueryOr = Query.query( new Criteria().orOperator( Criteria.where("name").is("ansel"), Criteria.where("payment").gte(100).lt(200) ) ); List<Order> results3 = mongoTemplate.find(differentColQueryOr, Order.class); printList(results3); }
3.5 Test sort
@Test public void testSort(){ Query query = new Query(); Sort sort = Sort.by(Sort.Direction.DESC,"payment"); query.with(sort); printList(mongoTemplate.find(query, Order.class)); System.out.println("================="); Query query1 = new Query(); Sort otehrSort = Sort.by(Sort.Order.desc("payment"), Sort.Order.asc("name")); query1.with(otehrSort); printList(mongoTemplate.find(query1,Order.class)); }
3.6 Test pagination
@Test public void testAggregation(){ TypedAggregation<Order> aggregation = TypedAggregation.newAggregation( Order.class, Aggregation.match(Criteria.where("payment").gte(120)), Aggregation.group("name").count().as("rows"), //跳过一行显示一行 Aggregation.skip(1), Aggregation.limit(1) ); AggregationResults<Map> aggregate = mongoTemplate.aggregate(aggregation, Map.class); List<Map> mappedResults = aggregate.getMappedResults(); for (Map mappedResult : mappedResults) { System.out.println(mappedResult); } }
ERROR
1.com.mongodb.MongoSocketOpenException: Exception opening socket
解决: 重启虚拟机