• mongodb


    一、快速入门

    数据结构介绍:人员信息

    {
            "_id" : ObjectId("59f938235d93fc4af8a37114"),
            "username" : "lison",
            "country" : "in11digo",
            "address" : {
                    "aCode" : "邮编",
                    "add" : "d11pff"
            },
            "favorites" : {
                    "movies" : ["杀破狼2","1dushe","雷神1"],
                    "cites" : ["1sh","1cs","1zz"]
            },
           "age" : 18"salary":NumberDecimal("2.099"),
           "lenght" :1.79
    }

    MongoDB脚本实现

    原生Java客户端

    <dependency>
        <groupId>org.mongodb</groupId>
        <artifactId>mongo-java-driver</artifactId>
        <version>3.9.0</version>
    </dependency>

    Tips:
    3.5.0最新版本加入了对pojo的支持;
    3.5.0最新版本增强对json的支持;
    mongodb原生客户端支持两种document和pojo模式的开发;

    Doc模式代码

    package com.enjoylearning.mongo.test;
    
    
    import java.math.BigDecimal;
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    import org.bson.Document;
    import org.bson.conversions.Bson;
    import org.junit.Before;
    import org.junit.Test;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    import com.mongodb.Block;
    import com.mongodb.MongoClient;
    import com.mongodb.client.FindIterable;
    import com.mongodb.client.MongoCollection;
    import com.mongodb.client.MongoDatabase;
    import com.mongodb.client.result.DeleteResult;
    import com.mongodb.client.result.UpdateResult;
    
    import static com.mongodb.client.model.Updates.*;
    import static com.mongodb.client.model.Filters.*;
    
    //原生java驱动 document的操作方式
    public class QuickStartJavaDocTest {
    
        private static final Logger logger = LoggerFactory.getLogger(QuickStartJavaDocTest.class);
        
        //数据库
        private MongoDatabase db;
        
        //文档集合
        private MongoCollection<Document> doc;
        
        //连接客户端(内置连接池)
        private MongoClient client;
        
        
        @Before
        public void init(){
            client = new MongoClient("116.62.222.124",27022);
            db =client.getDatabase("lison");
            doc = db.getCollection("users");
        }
        
        @Test
        public void insertDemo(){
            Document doc1 = new Document();
            doc1.append("username", "cang");
            doc1.append("country", "USA");
            doc1.append("age", 20);
            doc1.append("lenght", 1.77f);
            doc1.append("salary", new BigDecimal("6565.22"));//存金额,使用bigdecimal这个数据类型
            
            //添加“address”子文档
            Map<String, String> address1 = new HashMap<String, String>();
            address1.put("aCode", "0000");
            address1.put("add", "xxx000");
            doc1.append("address", address1);
            
            //添加“favorites”子文档,其中两个属性是数组
            Map<String, Object> favorites1 = new HashMap<String, Object>();
            favorites1.put("movies", Arrays.asList("aa","bb"));
            favorites1.put("cites", Arrays.asList("东莞","东京"));
            doc1.append("favorites", favorites1);
            
            Document doc2  = new Document();
            doc2.append("username", "Chen");
            doc2.append("country", "China");
            doc2.append("age", 30);
            doc2.append("lenght", 1.77f);
            doc2.append("salary", new BigDecimal("8888.22"));
            Map<String, String> address2 = new HashMap<>();
            address2.put("aCode", "411000");
            address2.put("add", "我的地址2");
            doc2.append("address", address2);
            Map<String, Object> favorites2 = new HashMap<>();
            favorites2.put("movies", Arrays.asList("东游记","一路向东"));
            favorites2.put("cites", Arrays.asList("珠海","东京"));
            doc2.append("favorites", favorites2);
            
            //使用insertMany插入多条数据
            doc.insertMany(Arrays.asList(doc1,doc2));
            
        }
        
        @Test
        public void testFind(){
            final List<Document> ret = new ArrayList<>();
            //block接口专门用于处理查询出来的数据
            Block<Document> printBlock = new Block<Document>() {
                @Override
                public void apply(Document t) {
                    logger.info(t.toJson());//打印数据
                    ret.add(t);
                }
                
            };       
            //select * from users  where favorites.cites has "东莞"、"东京"
            //db.users.find({ "favorites.cites" : { "$all" : [ "东莞" , "东京"]}})
            Bson all = all("favorites.cites", Arrays.asList("东莞","东京"));//定义数据过滤器,喜欢的城市中要包含"东莞"、"东京"
            FindIterable<Document> find = doc.find(all);
            find.forEach(printBlock);
            logger.info("------------------>"+String.valueOf(ret.size()));
            ret.removeAll(ret);
            
            
            //select * from users  where username like '%s%' and (contry= English or contry = USA)
            // db.users.find({ "$and" : [ { "username" : { "$regex" : ".*s.*"}} , { "$or" : [ { "country" : "English"} , { "country" : "USA"}]}]})
    
            String regexStr = ".*s.*";
            Bson regex = regex("username", regexStr);//定义数据过滤器,username like '%s%'
            Bson or = or(eq("country","English"),eq("country","USA"));//定义数据过滤器,(contry= English or contry = USA)
            Bson and = and(regex,or);
            FindIterable<Document> find2 = doc.find(and);
            find2.forEach(printBlock);
            logger.info("------------------>"+String.valueOf(ret.size()));
    
        }
        
        @Test
        public void testUpdate(){
            //update  users  set age=6 where username = 'lison' 
    //        db.users.updateMany({ "username" : "lison"},{ "$set" : { "age" : 6}},true)
    
            Bson eq = eq("username", "lison");//定义数据过滤器,username = 'lison' 
            Bson set = set("age", 8);//更新的字段.来自于Updates包的静态导入
            UpdateResult updateMany = doc.updateMany(eq, set);
            logger.info("------------------>"+String.valueOf(updateMany.getModifiedCount()));//打印受影响的行数
            
            //update users  set favorites.movies add "小电影2 ", "小电影3" where favorites.cites  has "东莞"
            //db.users.updateMany({ "favorites.cites" : "东莞"}, { "$addToSet" : { "favorites.movies" : { "$each" : [ "小电影2 " , "小电影3"]}}},true)
    
            Bson eq2 = eq("favorites.cites", "东莞");//定义数据过滤器,favorites.cites  has "东莞"
            Bson addEachToSet = addEachToSet("favorites.movies", Arrays.asList( "小电影2 ", "小电影3"));//更新的字段.来自于Updates包的静态导入
            UpdateResult updateMany2 = doc.updateMany(eq2, addEachToSet);
            logger.info("------------------>"+String.valueOf(updateMany2.getModifiedCount()));
        }
        
        @Test
        public void testDelete(){
            
            //delete from users where username = ‘lison’
            //db.users.deleteMany({ "username" : "lison"} )
            Bson eq = eq("username", "lison");//定义数据过滤器,username='lison'
            DeleteResult deleteMany = doc.deleteMany(eq);
            logger.info("------------------>"+String.valueOf(deleteMany.getDeletedCount()));//打印受影响的行数
            
            //delete from users where age >8 and age <25
            //db.users.deleteMany({"$and" : [ {"age" : {"$gt": 8}} , {"age" : {"$lt" : 25}}]})
    
            Bson gt = gt("age",8);//定义数据过滤器,age > 8,所有过滤器的定义来自于Filter这个包的静态方法,需要频繁使用所以静态导入
    //        Bson gt = Filter.gt("age",8);
            
            Bson lt = lt("age",25);//定义数据过滤器,age < 25
            Bson and = and(gt,lt);//定义数据过滤器,将条件用and拼接
            DeleteResult deleteMany2 = doc.deleteMany(and);
            logger.info("------------------>"+String.valueOf(deleteMany2.getDeletedCount()));//打印受影响的行数
        }
        
    
        
    
        
        
        
        
    
    }
    View Code

    POJO模式代码

    package com.enjoylearning.mongo.test;
    
    
    import static com.mongodb.client.model.Updates.*;
    import static com.mongodb.client.model.Filters.*;
    
    import java.math.BigDecimal;
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.List;
    
    import org.bson.Document;
    import org.bson.codecs.configuration.CodecRegistries;
    import org.bson.codecs.configuration.CodecRegistry;
    import org.bson.codecs.pojo.PojoCodecProvider;
    import org.bson.conversions.Bson;
    import org.junit.Before;
    import org.junit.Test;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    import com.enjoylearning.mongo.entity.Address;
    import com.enjoylearning.mongo.entity.Favorites;
    import com.enjoylearning.mongo.entity.User;
    import com.mongodb.Block;
    import com.mongodb.MongoClient;
    import com.mongodb.MongoClientOptions;
    import com.mongodb.ServerAddress;
    import com.mongodb.client.FindIterable;
    import com.mongodb.client.MongoCollection;
    import com.mongodb.client.MongoDatabase;
    import com.mongodb.client.model.Filters;
    import com.mongodb.client.model.Updates;
    import com.mongodb.client.result.DeleteResult;
    import com.mongodb.client.result.UpdateResult;
    
    //原生java驱动 Pojo的操作方式
    public class QuickStartJavaPojoTest {
    
        private static final Logger logger = LoggerFactory.getLogger(QuickStartJavaPojoTest.class);
        
        private MongoDatabase db;
        
        private MongoCollection<User> doc;
        
        private MongoClient client;
        
        
        @Before
        public void init(){
            //编解码器的list
            List<CodecRegistry> codecResgistes = new ArrayList<>();
            //list加入默认的编解码器集合
            codecResgistes.add(MongoClient.getDefaultCodecRegistry());
            //生成一个pojo的编解码器
            CodecRegistry pojoCodecRegistry = CodecRegistries.
                    fromProviders(PojoCodecProvider.builder().automatic(true).build());
            //list加入pojo的编解码器
            codecResgistes.add(pojoCodecRegistry);
            //通过编解码器的list生成编解码器注册中心
            CodecRegistry registry = CodecRegistries.fromRegistries(codecResgistes);
            
            //把编解码器注册中心放入MongoClientOptions
            //MongoClientOptions相当于连接池的配置信息
            MongoClientOptions build = MongoClientOptions.builder().
                    codecRegistry(registry).build();
    
            ServerAddress serverAddress = new ServerAddress("116.62.222.124",27022);
    
            client = new MongoClient(serverAddress, build);
            db =client.getDatabase("lison");
            doc = db.getCollection("users",User.class);
        }
        
    
        
        @Test
        public void insertDemo(){
            User user = new User();
            user.setUsername("cang");
            user.setCountry("USA");
            user.setAge(20);
            user.setLenght(1.77f);
            user.setSalary(new BigDecimal("6265.22"));
            
            //添加“address”子文档
            Address address1 = new Address();
            address1.setaCode("411222");
            address1.setAdd("sdfsdf");
            user.setAddress(address1);
            
            //添加“favorites”子文档,其中两个属性是数组
            Favorites favorites1 = new Favorites();
            favorites1.setCites(Arrays.asList("东莞","东京"));
            favorites1.setMovies(Arrays.asList("西游记","一路向西"));
            user.setFavorites(favorites1);
            
            
            User user1 = new User();
            user1.setUsername("chen");
            user1.setCountry("China");
            user1.setAge(30);
            user1.setLenght(1.77f);
            user1.setSalary(new BigDecimal("6885.22"));
            Address address2 = new Address();
            address2.setaCode("411000");
            address2.setAdd("我的地址2");
            user1.setAddress(address2);
            Favorites favorites2 = new Favorites();
            favorites2.setCites(Arrays.asList("珠海","东京"));
            favorites2.setMovies(Arrays.asList("东游记","一路向东"));
            user1.setFavorites(favorites2);
            
            
            //使用insertMany插入多条数据
            doc.insertMany(Arrays.asList(user,user1));
            
        }
        
        
        @Test
        public void testFind(){
            
            final List<User> ret = new ArrayList<>();
            Block<User> printBlock = new Block<User>() {
                @Override
                public void apply(User t) {
                    System.out.println(t.toString());
                    ret.add(t);
                }
                
            };
            
            //select * from users  where favorites.cites has "东莞"、"东京"
            //db.users.find({ "favorites.cites" : { "$all" : [ "东莞" , "东京"]}})
            Bson all = all("favorites.cites", Arrays.asList("东莞","东京"));//定义数据过滤器,喜欢的城市中要包含"东莞"、"东京"
            FindIterable<User> find = doc.find(all);
            find.forEach(printBlock);
            logger.info("------------------>"+String.valueOf(ret.size()));
            ret.removeAll(ret);
            
            //select * from users  where username like '%s%' and (contry= English or contry = USA)
            // db.users.find({ "$and" : [ { "username" : { "$regex" : ".*s.*"}} , { "$or" : [ { "country" : "English"} , { "country" : "USA"}]}]})
            String regexStr = ".*s.*";
            Bson regex = regex("username", regexStr);//定义数据过滤器,username like '%s%'
            Bson or = or(eq("country","English"),eq("country","USA"));//定义数据过滤器,(contry= English or contry = USA)
            FindIterable<User> find2 = doc.find(and(regex,or));
            find2.forEach(printBlock);
            logger.info("------------------>"+String.valueOf(ret.size()));
    
        }
        
        
        @Test
        public void testUpdate(){
               //update  users  set age=6 where username = 'lison' 
           //db.users.updateMany({ "username" : "lison"},{ "$set" : { "age" : 6}},true)
            Bson eq = eq("username", "lison");//定义数据过滤器,username = 'lison' 
            Bson set = set("age", 8);//更新的字段.来自于Updates包的静态导入
            UpdateResult updateMany = doc.updateMany(eq, set);
            logger.info("------------------>"+String.valueOf(updateMany.getModifiedCount()));//打印受影响的行数
            
            //update users  set favorites.movies add "小电影2 ", "小电影3" where favorites.cites  has "东莞"
            //db.users.updateMany({ "favorites.cites" : "东莞"}, { "$addToSet" : { "favorites.movies" : { "$each" : [ "小电影2 " , "小电影3"]}}},true)
            Bson eq2 = eq("favorites.cites", "东莞");//定义数据过滤器,favorites.cites  has "东莞"
            Bson addEachToSet = addEachToSet("favorites.movies", Arrays.asList( "小电影2 ", "小电影3"));//更新的字段.来自于Updates包的静态导入
            UpdateResult updateMany2 = doc.updateMany(eq2, addEachToSet);
            logger.info("------------------>"+String.valueOf(updateMany2.getModifiedCount()));
        }
        
        @Test
        public void testDelete(){
            
            //delete from users where username = ‘lison’
            //db.users.deleteMany({ "username" : "lison"} )
            Bson eq = eq("username", "lison");//定义数据过滤器,username='lison'
            DeleteResult deleteMany = doc.deleteMany(eq);
            logger.info("------------------>"+String.valueOf(deleteMany.getDeletedCount()));//打印受影响的行数
            
            //delete from users where age >8 and age <25
            //db.users.deleteMany({"$and" : [ {"age" : {"$gt": 8}} , {"age" : {"$lt" : 25}}]})
            Bson gt = gt("age",8);//定义数据过滤器,age > 8,所有过滤器的定义来自于Filter这个包的静态方法,需要频繁使用所以静态导入
            
            Bson lt = lt("age",25);//定义数据过滤器,age < 25
            Bson and = and(gt,lt);//定义数据过滤器,将条件用and拼接
            DeleteResult deleteMany2 = doc.deleteMany(and);
            logger.info("------------------>"+String.valueOf(deleteMany2.getDeletedCount()));//打印受影响的行数
        }
        
    
        
    
        
        
        
        
    
    }
    View Code

    Spring-data-mongodb客户端

    <dependency>
    <groupId>org.springframework.data</groupId>
    <artifactId>spring-data-mongodb</artifactId>
    <version>1.10.18.RELEASE</version>
    </dependency>

    Tips:
    spring-data-mongodb的最新版本是2.x.x,如果是spring为5.0版本以上的才推荐使用;
    spring-data-mongodb的1.10.18版本基于spring4.3.x开发,但是默认依赖的mongodb驱动为2.14.3,可以将mongodb的驱动设置为3.9.0的版本;
    spring-data-mongodb一般使用pojo的方式开发;

    Spring POJO开发模式代码

    package com.enjoylearning.mongo.test;
    
    
    import static org.springframework.data.mongodb.core.query.Criteria.where;
    import static org.springframework.data.mongodb.core.query.Query.query;
    import static org.springframework.data.mongodb.core.query.Update.update;
    
    import java.math.BigDecimal;
    import java.util.Arrays;
    import java.util.List;
    
    import javax.annotation.Resource;
    
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.data.mongodb.core.MongoOperations;
    import org.springframework.data.mongodb.core.query.Criteria;
    import org.springframework.data.mongodb.core.query.Query;
    import org.springframework.data.mongodb.core.query.Update;
    import org.springframework.test.context.ContextConfiguration;
    import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
    
    import com.enjoylearning.mongo.entity.Address;
    import com.enjoylearning.mongo.entity.Favorites;
    import com.enjoylearning.mongo.entity.User;
    import com.mongodb.WriteResult;
    
    //spring Pojo的操作方式
    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration("classpath:applicationContext.xml")
    public class QuickStartSpringPojoTest {
    
        private static final Logger logger = LoggerFactory.getLogger(QuickStartSpringPojoTest.class);
        
        @Resource
        private MongoOperations tempelate;
        
    
        @Test
        public void insertDemo(){
            User user = new User();
            user.setUsername("cang");
            user.setCountry("USA");
            user.setAge(20);
            user.setLenght(1.77f);
            user.setSalary(new BigDecimal("6265.22"));
            
            //添加“address”子文档
            Address address1 = new Address();
            address1.setaCode("411222");
            address1.setAdd("sdfsdf");
            user.setAddress(address1);
            
            //添加“favorites”子文档,其中两个属性是数组
            Favorites favorites1 = new Favorites();
            favorites1.setCites(Arrays.asList("东莞","东京"));
            favorites1.setMovies(Arrays.asList("西游记","一路向西"));
            user.setFavorites(favorites1);
            
            
            User user1 = new User();
            user1.setUsername("chen");
            user1.setCountry("China");
            user1.setAge(30);
            user1.setLenght(1.77f);
            user1.setSalary(new BigDecimal("6885.22"));
            Address address2 = new Address();
            address2.setaCode("411000");
            address2.setAdd("我的地址2");
            user1.setAddress(address2);
            Favorites favorites2 = new Favorites();
            favorites2.setCites(Arrays.asList("珠海","东京"));
            favorites2.setMovies(Arrays.asList("东游记","一路向东"));
            user1.setFavorites(favorites2);
            
            tempelate.insertAll(Arrays.asList(user,user1));
        }
        
        @Test
        public void testFind(){
            
            //select * from users  where favorites.cites has "东莞"、"东京"
            //db.users.find({ "favorites.cites" : { "$all" : [ "东莞" , "东京"]}})
            Criteria all = where("favorites.cites").all(Arrays.asList("东莞","东京"));
            List<User> find = tempelate.find(query(all), User.class);
            System.out.println(find.size());
            for (User user : find) {
                System.out.println(user.toString());
            }
            
            
            //select * from users  where username like '%s%' and (contry= English or contry = USA)
            // db.users.find({ "$and" : [ { "username" : { "$regex" : ".*s.*"}} , { "$or" : [ { "country" : "English"} , { "country" : "USA"}]}]})
            String regexStr = ".*s.*";
            //username like '%s%'
            Criteria regex = where("username").regex(regexStr);
            //contry= EngLish
            Criteria or1 = where("country").is("English");
            //contry= USA
            Criteria or2 = where("country").is("USA");
            
            Criteria or = new Criteria().orOperator(or1,or2);
            
            Query query = query(new Criteria().andOperator(regex,or));
            
            List<User> find2 = tempelate.find(query, User.class);
            
            System.out.println(find2.size());
            for (User user : find2) {
                System.out.println(user.toString());
            }
        }
        
    
        
        @Test
        public void testUpdate(){
               //update  users  set age=6 where username = 'lison' 
           //db.users.updateMany({ "username" : "lison"},{ "$set" : { "age" : 6}},true)
            Query query = query(where("username").is("lison"));
            Update update = update("age", 6);
            WriteResult updateFirst = tempelate.updateMulti(query, update, User.class);
            System.out.println(updateFirst.getN());
            
            //update users  set favorites.movies add "小电影2 ", "小电影3" where favorites.cites  has "东莞"
            //db.users.updateMany({ "favorites.cites" : "东莞"}, { "$addToSet" : { "favorites.movies" : { "$each" : [ "小电影2 " , "小电影3"]}}},true)
            query = query(where("favorites.cites").is("东莞"));
            update = new Update().addToSet("favorites.movies").each("小电影2 ", "小电影3");
            WriteResult updateMulti = tempelate.updateMulti(query, update, User.class);
            System.out.println("--------------------->"+updateMulti.getN());
        }
        
        @Test
        public void testDelete(){
            
            //delete from users where username = ‘lison’
            //db.users.deleteMany({ "username" : "lison"} )
            Query query = query(where("username").is("lison"));
            WriteResult remove = tempelate.remove(query, User.class);
            System.out.println("--------------------->"+remove.getN());
            
            //delete from users where age >8 and age <25
            //db.users.deleteMany({"$and" : [ {"age" : {"$gt": 8}} , {"age" : {"$lt" : 25}}]})
            query = query(new Criteria().andOperator(where("age").gt(8),where("age").lt(25)));
            WriteResult remove2 = tempelate.remove(query, User.class);
            System.out.println("--------------------->"+remove2.getN());
            
            
            
        }
    
        
            
        
        
        
    
    }
    View Code

    开发框架版本选择

    Java驱动与MongoDB兼容性

    Tips:  考虑到MongoDB客户端强大的向下兼容性,建议使用3.9.0版本

     spring data mongo 与java mongo驱动兼容性

    Tips:Spring Data MongoDB 1.x 与 2.x之间区别比较大,请点击我

    想要使用spring mongoDB 2.x的新API,同时想使用3.5.0以上版本的java驱动?

    spring-data-mongodb的1.10.18版本
    java mongodb client 3.9
    spring 4.3.13以上

    MongoDB数据类型

    二、查询

     查询概要

    MongoDB 查询数据的语法格式如下:
    db.collection.find(query, projection)
    query :可选,使用查询操作符指定查询条件
    projection :可选,使用投影操作符指定返回的键。查询时返回文档中所有键值, 只需省略该参数即可(默认省略)。
    注意:0表示字段排除,非0表示字段选择并排除其他字段,所有字段必须设置同样的值;
    需要以易读的方式来读取数据,可以使用 pretty() 方法;
    举例子:db.users.find({"$and":[{"username":"lison"},{"age":18}]},{"username":0,"age":0})

    查询选择器

    查询选择器实战

    (1)client指定端口和ip连接mongodb
    ./mongo localhost:27022
    (2)in选择器示例:
    db.users.find({"username":{"$in":["lison", "mark", "james"]}}).pretty()
    查询姓名为lison、mark和james这个范围的人
    (3)exists选择器示例:
    db.users.find({"lenght":{"$exists":true}}).pretty()
    判断文档有没有关心的字段
    (4)not选择器示例:
    db.users.find({"lenght":{"$not":{"$gte":1.77}}}).pretty()
    查询高度小于1.77或者没有身高的人
    not语句 会把不包含查询语句字段的文档 也检索出来

    查询选择

    映射

    字段选择并排除其他字段:db.users.find({},{'username':1})
    字段排除:db.users.find({},{'username':0})

    排序

    sort():db.users.find().sort({"username":1}).pretty()
    1:升序 -1:降序

    跳过和限制

    skip(n):跳过n条数据
    limit(n):限制n条数据
    e.g: db.users.find().sort({"username":1}).limit(2).skip(2)

    查询唯一值

    distinct():查询指定字段的唯一值,e.g:db.users.distinct("username")

    字符串数组选择查询

    1.数组单元素查询
    db.users.find({"favorites.movies":"蜘蛛侠"})
    查询数组中包含"蜘蛛侠"

    2.数组精确查找
    db.users.find({"favorites.movies":[ "杀破狼2", "战狼", "雷神1" ]},{"favorites.movies":1})
    查询数组等于[ "杀破狼2", "战狼", "雷神1" ]的文档,严格按照数量、顺序;

    3.数组多元素查询
    db.users.find({"favorites.movies":{"$all":[ "雷神1", "战狼" ]}},{"favorites.movies":1})
    查询数组包含["雷神1", "战狼" ]的文档,跟顺序无关,跟数量有关

    db.users.find({"favorites.movies":{"$in":[ "雷神1", "战狼" ]}},{"favorites.movies":1})
    查询数组包含["雷神1", "战狼" ]中任意一个的文档,跟顺序无关,跟数量无关

    4.索引查询
    db.users.find({"favorites.movies.0":"妇联4"},{"favorites.movies":1})
    查询数组中第一个为"妇联4"的文档

    5.返回数组子集
    db.users.find({},{"favorites.movies":{"$slice":[1,2]},"favorites":1})
    $slice可以取两个元素数组,分别表示跳过和限制的条数;

    对象数组选择查询

    1. 单元素查询
    db.users.find({"comments":{
    "author" : "lison6",
    "content" : "lison评论6","commentTime" : ISODate("2017-06-06T00:00:00Z")}})
    备注:对象数组精确查找
    2.查找lison1 或者 lison12评论过的user ($in查找符)
    db.users.find({"comments.author":{"$in":["lison1","lison12"]}}).pretty()
    备注:跟数量无关,跟顺序无关;
    3.查找lison1 和 lison12都评论过的user
    db.users.find({"comments.author":{"$all":["lison12","lison1"]}}).pretty()
    备注:跟数量有关,跟顺序无关;
    4.查找lison5评语为包含"苍老师"关键字的user($elemMatch查找符)
    db.users.find({"comments":{"$elemMatch":{"author" : "lison5",
    "content" : { "$regex" : ".*苍老师.*"}}}}) .pretty()
    备注:数组中对象数据要符合查询对象里面所有的字段,$全元素匹配,和顺序无关;

    Java客户端解析

    原生Java驱动

    MongoClient → MongoDatabase →MongoCollection
    MongoClient被设计成线程安全、可以被多线程共享的。通常访问数据库集群的应用只需要一个实例
    如果需要使用pojo对象读写,需要将PojoCodecProvider注入到client中
    查询和更新的API类
    查询器:com.mongodb.client.model.Filters
    更新器:com.mongodb.client.model.Updates
    投影器:com.mongodb.client.model.Projections

    package com.enjoylearning.lison.mongodb;
    
    import static com.mongodb.client.model.Filters.*;
    import static com.mongodb.client.model.Projections.*;
    import static com.mongodb.client.model.Sorts.*;
    import static com.mongodb.client.model.Aggregates.*;
    
    import java.text.ParseException;
    import java.text.SimpleDateFormat;
    import java.time.LocalDateTime;
    import java.time.ZoneId;
    import java.time.ZonedDateTime;
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.Date;
    import java.util.List;
    
    import javax.annotation.Resource;
    
    import org.bson.BSON;
    import org.bson.BsonDocument;
    import org.bson.Document;
    import org.bson.codecs.configuration.CodecRegistries;
    import org.bson.codecs.configuration.CodecRegistry;
    import org.bson.codecs.pojo.PojoCodecProvider;
    import org.bson.conversions.Bson;
    import org.junit.Before;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.junit.runner.manipulation.Filter;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.data.mongodb.core.MongoOperations;
    import org.springframework.test.context.ContextConfiguration;
    import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
    
    import com.mongodb.Block;
    import com.mongodb.MongoClient;
    import com.mongodb.MongoClientOptions;
    import com.mongodb.ServerAddress;
    import com.mongodb.WriteConcern;
    import com.mongodb.client.AggregateIterable;
    import com.mongodb.client.FindIterable;
    import com.mongodb.client.MongoCollection;
    import com.mongodb.client.MongoDatabase;
    import com.mongodb.client.model.Accumulators;
    import com.mongodb.client.model.Filters;
    import com.mongodb.client.model.Projections;
    import com.mongodb.client.model.PushOptions;
    import com.mongodb.client.model.Updates;
    import com.mongodb.client.result.UpdateResult;
    import com.mongodb.operation.OrderBy;
    
    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration("classpath:applicationContext.xml")
    public class JavaQueryTest {
    
        private static final Logger logger = LoggerFactory
                .getLogger(JavaQueryTest.class);
    
        private MongoDatabase db;
    
        private MongoCollection<Document> collection;
    
        private MongoCollection<Document> orderCollection;
    
        @Resource(name="mongo")
        private MongoClient client;
    
        @Before
        public void init() {
            db = client.getDatabase("lison");
            collection = db.getCollection("users");
            orderCollection = db.getCollection("ordersTest");
        }
    
        // -----------------------------操作符使用实例------------------------------------------
    
        // db.users.find({"username":{"$in":["lison", "mark", "james"]}}).pretty()
        // 查询姓名为lison、mark和james这个范围的人
        @Test
        public void testInOper() {
            Bson in = in("username", "lison", "mark", "james");
            FindIterable<Document> find = collection.find(in);
            printOperation(find);
        }
    
        // db.users.find({"lenght":{"$exists":true}}).pretty()
        // 判断文档有没有关心的字段
        @Test
        public void testExistsOper() {
            Bson exists = exists("lenght", true);
            FindIterable<Document> find = collection.find(exists);
            printOperation(find);
        }
    
        // db.users.find().sort({"username":1}).limit(1).skip(2)
        // 测试sort,limit,skip
        @Test
        public void testSLSOper() {
            Document sort = new Document("username", 1);
            FindIterable<Document> find = collection.find().sort(sort).limit(1).skip(2);
            printOperation(find);
        }
    
        // db.users.find({"lenght":{"$not":{"$gte":1.77}}}).pretty()
        // 查询高度小于1.77或者没有身高的人
        // not语句 会把不包含查询语句字段的文档 也检索出来
    
        @Test
        public void testNotOper() {
            Bson gte = gte("lenght", 1.77);
            Bson not = not(gte);
            FindIterable<Document> find = collection.find(not);
            printOperation(find);
        }
    
        // -----------------------------字符串数组查询实例------------------------------------------
    
        // db.users.find({"favorites.movies":"蜘蛛侠"})
        // 查询数组中包含"蜘蛛侠"
        @Test
        public void testArray1() {
            Bson eq = eq("favorites.movies", "蜘蛛侠");
            FindIterable<Document> find = collection.find(eq);
            printOperation(find);
        }
    
        // db.users.find({"favorites.movies":[ "妇联4","杀破狼2", "战狼", "雷神1","神奇动物在哪里"]},{"favorites.movies":1})
        // 查询数组等于[ “杀破狼2”, “战狼”, “雷神1” ]的文档,严格按照数量、顺序;
    
        @Test
        public void testArray2() {
            Bson eq = eq("favorites.movies", Arrays.asList("妇联4","杀破狼2", "战狼", "雷神1","神奇动物在哪里"));
            FindIterable<Document> find = collection.find(eq);
            printOperation(find);
        }
    
    
        //数组多元素查询
        @Test
        public void testArray3() {
            
            // db.users.find({"favorites.movies":{"$all":[ "雷神1", "战狼"]}},{"favorites.movies":1})
            // 查询数组包含["雷神1", "战狼" ]的文档,跟顺序无关
            Bson all = all("favorites.movies", Arrays.asList("雷神1", "战狼"));
            FindIterable<Document> find = collection.find(all);
            printOperation(find);        
    //        db.users.find({"favorites.movies":{"$in":[ "雷神1", "战狼" ]}},{"favorites.movies":1})
    //        查询数组包含[“雷神1”, “战狼” ]中任意一个的文档,跟顺序无关,跟数量无关
            Bson in = in("favorites.movies", Arrays.asList("雷神1", "战狼"));
            find = collection.find(in);
            printOperation(find);
        }
    
        // // db.users.find({"favorites.movies.0":"妇联4"},{"favorites.movies":1})
        // 查询数组中第一个为"妇联4"的文档
    
        @Test
        public void testArray4() {
            Bson eq = eq("favorites.movies.0", "妇联4");
            FindIterable<Document> find = collection.find(eq);
            printOperation(find);
        }
    
        // db.users.find({},{"favorites.movies":{"$slice":[1,2]},"favorites":1})
        // $slice可以取两个元素数组,分别表示跳过和限制的条数;
    
        @Test
        public void testArray5() {
            Bson slice = slice("favorites.movies", 1, 2);
            Bson include = include("favorites");
            Bson projection = fields(slice, include);
            FindIterable<Document> find = collection.find().projection(projection);
            printOperation(find);
        }
    
        // -----------------------------对象数组查询实例------------------------------------------
        
        
        //db.users.find({"comments":{"author":"lison6","content":"lison评论6","commentTime":ISODate("2017-06-06T00:00:00Z")}})
        //备注:对象数组精确查找
        @Test
        public void testObjArray1() throws ParseException {
            SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
            Date commentDate = formatter.parse("2017-06-06 08:00:00");
            
            Document comment = new Document().append("author", "lison6")
                                             .append("content", "lison评论6")
                                             .append("commentTime", commentDate);
            Bson eq = eq("comments", comment);
            FindIterable<Document> find = collection.find(eq);
            printOperation(find);    }
    
    
        //数组多元素查询
        @Test
        public void testObjArray2() {
            
            
    //        查找lison1 或者 lison12评论过的user ($in查找符) 
    //        db.users.find({"comments.author":{"$in":["lison1","lison12"]}}).pretty()
    //          备注:跟数量无关,跟顺序无关;
    
            Bson in = in("comments.author", Arrays.asList("lison1","lison12"));
            FindIterable<Document> find = collection.find(in);
            printOperation(find);        
            
    //        查找lison1 和 lison12都评论过的user
    //        db.users.find({"comments.author":{"$all":["lison12","lison1"]}}).pretty()
    //         备注:跟数量有关,跟顺序无关;
    
            Bson all = all("comments.author", Arrays.asList("lison12","lison1"));
            find = collection.find(all);
            printOperation(find);    
        }
        
        
        
        //查找lison5评语为包含“苍老师”关键字的user($elemMatch查找符) 
    //    db.users.find({"comments":{"$elemMatch":{"author" : "lison5", "content" : { "$regex" : ".*苍老师.*"}}}})
    //备注:数组中对象数据要符合查询对象里面所有的字段,$全元素匹配,和顺序无关;
    
        @Test
        public void testObjArray3() throws ParseException {
            Bson eq = eq("author","lison5");
            Bson regex = regex("content", ".*苍老师.*");
            Bson elemMatch = Filters.elemMatch("comments", and(eq,regex));
            FindIterable<Document> find = collection.find(elemMatch);
            printOperation(find);    
        }
        
        
        // dbRef测试
        // dbref其实就是关联关系的信息载体,本身并不会去关联数据
        @Test
        public void dbRefTest() {
            FindIterable<Document> find = collection.find(eq("username", "lison"));
            printOperation(find);
        }
    
        
        
        
        // ---------------------------------------------------------------------------
    
        //返回对象的处理器,打印每一行数据
        private Block<Document> getBlock(final List<Document> ret) {
            Block<Document> printBlock = new Block<Document>() {
                @Override
                public void apply(Document t) {
                    logger.info("---------------------");
                    logger.info(t.toJson());
                    logger.info("---------------------");
                    ret.add(t);
                }
            };
            return printBlock;
        }
    
        //打印查询出来的数据和查询的数据量
        private void printOperation( FindIterable<Document> find) {
            final List<Document> ret = new ArrayList<Document>();
            Block<Document> printBlock = getBlock(ret);
            find.forEach(printBlock);
            System.out.println(ret.size());
            ret.removeAll(ret);
        }
    
        
        private void printOperation(List<Document> ret, Block<Document> printBlock,
                AggregateIterable<Document> aggregate) {
            aggregate.forEach(printBlock);
            System.out.println(ret.size());
            ret.removeAll(ret);
    
        }
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
    
        @Test
        // 测试elemMatch操作符,数组中对象数据要符合查询对象里面所有的字段
        // 查找lison5评语为“lison是苍老师的小迷弟”的人
        // db.users.find({"comments":{"$elemMatch":{"author" : "lison5","content" :
        // "lison是苍老师的小迷弟"}}}) .pretty()
        public void testElemMatch() {
            Document filter = new Document().append("author", "lison5").append(
                    "content", "lison是苍老师的小迷弟");
            Bson elemMatch = Filters.elemMatch("comments", filter);
    
            FindIterable<Document> find = collection.find(elemMatch);
    
            printOperation(find);
    
        }
    
        /**
         * db.users.updateOne({"username":"lison",}, {"$push": { "comments": {
         * $each: [{ "author" : "james", "content" : "lison是个好老师!", "commentTime" :
         * ISODate("2018-01-06T04:26:18.354Z") } ], $sort: {"commentTime":-1} }}});
         */
        @Test
        // 新增评论时,使用$sort运算符进行排序,插入评论后,再按照评论时间降序排序
        public void demoStep1() {
            Bson filter = eq("username", "lison");
            Document comment = new Document().append("author", "cang")
                    .append("content", "lison是我的粉丝")
                    .append("commentTime", new Date());
            // $sort: {"commentTime":-1}
            Document sortDoc = new Document().append("commentTime", -1);
            PushOptions sortDocument = new PushOptions().sortDocument(sortDoc);
            // $each
            Bson pushEach = Updates.pushEach("comments", Arrays.asList(comment),
                    sortDocument);
    
            UpdateResult updateOne = collection.updateOne(filter, pushEach);
            System.out.println(updateOne.getModifiedCount());
        }
    
        @Test
        // 查看人员时加载最新的三条评论;
        // db.users.find({"username":"lison"},{"comments":{"$slice":[0,3]}}).pretty()
        public void demoStep2() {
            FindIterable<Document> find = collection.find(eq("username", "lison"))
                    .projection(slice("comments", 0, 3));
            printOperation(find);
        }
    
        @Test
        // 点击评论的下一页按钮,新加载三条评论
        // db.users.find({"username":"lison"},{"comments":{"$slice":[3,3]},"$id":1}).pretty();
        public void demoStep3() {
            // {"username":"lison"}
            Bson filter = eq("username", "lison");
            // "$slice":[3,3]
            Bson slice = slice("comments", 3, 3);
            // "$id":1
            Bson includeID = include("id");
    
            // {"comments":{"$slice":[3,3]},"$id":1})
            Bson projection = fields(slice, includeID);
    
            FindIterable<Document> find = collection.find(filter).projection(
                    projection);
            printOperation(find);
        }
    
        @Test
        /**
         * db.users.aggregate([{"$match":{"username":"lison"}},
                               {"$unwind":"$comments"},
                               {$sort:{"comments.commentTime":-1}},
                               {"$project":{"comments":1}},
                               {"$skip":6},
                               {"$limit":3}])
         */
        // 如果有多种排序需求怎么处理,使用聚合
        public void demoStep4() {
            final List<Document> ret = new ArrayList<Document>();
            Block<Document> printBlock = getBlock(ret);
            List<Bson> aggregates = new ArrayList<Bson>();
    
            aggregates.add(match(eq("username", "lison")));
            aggregates.add(unwind("$comments"));
            aggregates.add(sort(orderBy(ascending("comments.commentTime"))));
            aggregates.add(project(fields(include("comments"))));
            aggregates.add(skip(0));
            aggregates.add(limit(3));
    
            AggregateIterable<Document> aggregate = collection
                    .aggregate(aggregates);
    
            printOperation(ret, printBlock, aggregate);
        }
    
        @Test
        public void aggretionTest() {
            Block<Document> printBlock = new Block<Document>() {
                @Override
                public void apply(Document t) {
                    logger.info("---------------------");
                    System.out.println(t.toJson());
                    logger.info("---------------------");
                }
            };
    
            // 定义数据的处理类
            // final List<Document> ret = new ArrayList<Document>();
            // //
            // Document filter = new Document().append("useCode","tony");
            //
            // FindIterable<Document> find = orderCollection.find(filter);
            //
            // printOperation(ret, printBlock, find);
    
            // db.ordersTest.aggregate([{"$group":{_id:"$useCode",count: { $sum:
            // "$price" } } }])
    
            List<Bson> aggregates = new ArrayList<Bson>();
            aggregates.add(group("$useCode", Accumulators.sum("sum", "$price")));
            AggregateIterable<Document> aggregate = orderCollection
                    .aggregate(aggregates);
            aggregate.forEach(printBlock);
        }
    
    
    
    
    }
    View Code

    Spring MongoDB解析

    Xml配置文件

    <!-- mongodb连接池配置 -->
    <mongo:mongo-client host="192.168.1.129" port="27017">
    <mongo:client-options 
          write-concern="ACKNOWLEDGED"
          connections-per-host="100"
          threads-allowed-to-block-for-connection-multiplier="5"
          max-wait-time="120000"
      connect-timeout="10000"/> 
    </mongo:mongo-client>>
    
    <!-- mongodb数据库工厂配置 -->
    <mongo:db-factory dbname="lison" mongo-ref="mongo" />
    
    <!-- mongodb模板配置 -->
    <bean id="anotherMongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
    <constructor-arg name="mongoDbFactory" ref="mongoDbFactory" />
    <property name="writeResultChecking" value="EXCEPTION"></property>
    </bean>

    Spring mongodb开发
    模板模式,基于MongoOperations进行操作,基于pojo的操作,配合@document注解开发;
    查询和更新的API类
    查询器:org.springframework.data.mongodb.core.query.Query
    查询条件:org.springframework.data.mongodb.core.query.Criteria
    更新器:org.springframework.data.mongodb.core.query.Update

    Spring实现代码

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
        xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:mongo="http://www.springframework.org/schema/data/mongo"
        xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
            http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
            http://www.springframework.org/schema/data/mongo http://www.springframework.org/schema/data/mongo/spring-mongo.xsd">
    
        <!-- <context:property-placeholder location="classpath:/com/myapp/mongodb/config/mongo.properties" 
            /> -->
        <context:component-scan base-package="com.enjoylearning.mongo.config">
        
        </context:component-scan>
        
        
        
        
        <!-- mongodb连接池配置 -->
        <!-- <mongo:mongo-client host="192.168.1.142" port="27022" credentials="lison:lison@lison"> --> 
        <mongo:mongo-client host="116.62.222.124" port="27022" > 
            <!-- replica-set="192.168.1.142:27017,192.168.1.142:27018,192.168.1.142:27017" -->
            <mongo:client-options 
                  write-concern="ACKNOWLEDGED"
                  connections-per-host="1"
                  threads-allowed-to-block-for-connection-multiplier="5"
                  max-wait-time="120000"
                  connect-timeout="10000"/> 
        </mongo:mongo-client>
        
        <!-- mongodb数据库工厂配置 -->
        <mongo:db-factory dbname="lison" mongo-ref="mongo" />
        
         <mongo:mapping-converter base-package="com.enjoylearning.mongodb.entity">
              <mongo:custom-converters>
                  <mongo:converter>
                    <bean class="com.enjoylearning.mongo.convert.BigDecimalToDecimal128Converter"/>
                  </mongo:converter>
                  <mongo:converter>
                    <bean class="com.enjoylearning.mongo.convert.Decimal128ToBigDecimalConverter"/>
                  </mongo:converter>
            </mongo:custom-converters>
        </mongo:mapping-converter>
    
        <!-- mongodb模板配置 -->
        <bean id="anotherMongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
            <constructor-arg name="mongoDbFactory" ref="mongoDbFactory" />
            <constructor-arg name="mongoConverter" ref="mappingConverter"/>
            <property name="writeResultChecking" value="EXCEPTION"></property>
        </bean>
    
    
    
    </beans>
    View Code
    package com.enjoylearning.lison.mongodb;
    
    
    
    import static org.springframework.data.mongodb.core.aggregation.Aggregation.*;
    import static org.springframework.data.mongodb.core.query.Criteria.*;
    import static org.springframework.data.mongodb.core.query.Query.*;
    
    import java.text.ParseException;
    import java.text.SimpleDateFormat;
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.Date;
    import java.util.List;
    
    import javax.annotation.Resource;
    
    import org.bson.Document;
    import org.bson.conversions.Bson;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.data.domain.Sort;
    import org.springframework.data.domain.Sort.Direction;
    import org.springframework.data.mongodb.core.MongoOperations;
    import org.springframework.data.mongodb.core.aggregation.Aggregation;
    import org.springframework.data.mongodb.core.aggregation.AggregationResults;
    import org.springframework.data.mongodb.core.query.Criteria;
    import org.springframework.data.mongodb.core.query.Query;
    import org.springframework.data.mongodb.core.query.Update;
    import org.springframework.data.mongodb.core.query.Update.PushOperatorBuilder;
    import org.springframework.test.context.ContextConfiguration;
    import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
    
    import com.enjoylearning.mongo.entity.Comment;
    import com.enjoylearning.mongo.entity.User;
    import com.mongodb.Block;
    import com.mongodb.WriteResult;
    import com.mongodb.client.FindIterable;
    import com.mongodb.client.model.Filters;
    
    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration("classpath:applicationContext.xml")
    public class SpringQueryTest {
    
        private static final Logger logger = LoggerFactory
                .getLogger(SpringQueryTest.class);
    
        @Resource
        private MongoOperations tempelate;
        
        
        
        // -----------------------------操作符使用实例------------------------------------------
    
        // db.users.find({"username":{"$in":["lison", "mark", "james"]}}).pretty()
        // 查询姓名为lison、mark和james这个范围的人
        @Test
        public void testInOper() {
            Query query = query(where("username").in("lison", "mark", "james"));
            List<User> find = tempelate.find(query, User.class);
            printUsers(find);
            
            
        }
    
    
        // db.users.find({"lenght":{"$exists":true}}).pretty()
        // 判断文档有没有关心的字段
        @Test
        public void testExistsOper() {
    
            Query query = query(where("lenght").exists(true));
            List<User> find = tempelate.find(query, User.class);
            printUsers(find);
        
        }
    
        // db.users.find().sort({"username":1}).limit(1).skip(2)
        // 测试sort,limit,skip
        @Test
        public void testSLSOper() {
            
            Query query = query(where(null)).with(new Sort(new Sort.Order(Direction.ASC, "username"))).limit(1).skip(2);
            List<User> find = tempelate.find(query, User.class);
            printUsers(find);
    
        }
    
        // db.users.find({"lenght":{"$not":{"$gte":1.77}}}).pretty()
        // 查询高度小于1.77或者没有身高的人
        // not语句 会把不包含查询语句字段的文档 也检索出来
    
        @Test
        public void testNotOper() {
            Query query = query(where("lenght").not().gte(1.77));
            List<User> find = tempelate.find(query, User.class);
            printUsers(find);
            
    
        }
    
    
        
        
        // -----------------------------字符串数组查询实例------------------------------------------
    
        // db.users.find({"favorites.movies":"蜘蛛侠"})
        // 查询数组中包含"蜘蛛侠"
        @Test
        public void testArray1() {
            Query query = query(where("favorites.movies").is("蜘蛛侠"));
            List<User> find = tempelate.find(query, User.class);
            printUsers(find);
        }
    
        // db.users.find({"favorites.movies":[ "妇联4","杀破狼2", "战狼", "雷神1","神奇动物在哪里"]},{"favorites.movies":1})
        // 查询数组等于[ “杀破狼2”, “战狼”, “雷神1” ]的文档,严格按照数量、顺序;
    
        @Test
        public void testArray2() {
            Query query = query(where("favorites.movies").is(Arrays.asList("妇联4","杀破狼2", "战狼", "雷神1","神奇动物在哪里")));
            List<User> find = tempelate.find(query, User.class);
            printUsers(find);
        }
    
    
        //数组多元素查询
        @Test
        public void testArray3() {
            // db.users.find({"favorites.movies":{"$all":[ "雷神1", "战狼"]}},{"favorites.movies":1})
            // 查询数组包含["雷神1", "战狼" ]的文档,跟顺序无关
            
            Query query = query(where("favorites.movies").all(Arrays.asList("雷神1", "战狼")));
            List<User> find = tempelate.find(query, User.class);
            printUsers(find);
            
            
    //        db.users.find({"favorites.movies":{"$in":[ "雷神1", "战狼" ]}},{"favorites.movies":1})
    //        查询数组包含[“雷神1”, “战狼” ]中任意一个的文档,跟顺序无关,跟数量无关
             query = query(where("favorites.movies").in(Arrays.asList("雷神1", "战狼")));
             find = tempelate.find(query, User.class);
             printUsers(find);
        }
    
        // // db.users.find({"favorites.movies.0":"妇联4"},{"favorites.movies":1})
        // 查询数组中第一个为"妇联4"的文档
    
        @Test
        public void testArray4() {
            Query query = query(where("favorites.movies.0").is("妇联4"));
            List<User> find = tempelate.find(query, User.class);
            printUsers(find);
        }
    
        // db.users.find({},{"favorites.movies":{"$slice":[1,2]},"favorites":1})
        // $slice可以取两个元素数组,分别表示跳过和限制的条数;
    
        @Test
        public void testArray5() {
            Query query = query(where(null));
            query.fields().include("favorites").slice("favorites.movies", 1, 2);
            List<User> find = tempelate.find(query, User.class);
            printUsers(find);
        }
    
        // -----------------------------对象数组查询实例------------------------------------------
        
        
        //db.users.find({"comments":{"author":"lison6","content":"lison评论6","commentTime":ISODate("2017-06-06T00:00:00Z")}})
        //备注:对象数组精确查找
        //坑:居然和属性定义的顺序有关
        @Test
        public void testObjArray1() throws ParseException {
            SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
            Date commentDate = formatter.parse("2017-06-06 08:00:00");
            Comment comment = new Comment();
            comment.setAuthor("lison6");
            comment.setCommentTime(commentDate);
            comment.setContent("lison评论6");
    
            Query query = query(where("comments").is(comment));
            List<User> find = tempelate.find(query, User.class);
            printUsers(find);
        }
    
    
        //数组多元素查询
        @Test
        public void testObjArray2() {
            
            
            
    //        查找lison1 或者 lison12评论过的user ($in查找符) 
    //        db.users.find({"comments.author":{"$in":["lison1","lison12"]}}).pretty()
    //          备注:跟数量无关,跟顺序无关;
    
            Query query = query(where("comments.author").in(Arrays.asList("lison1","lison12")));
            List<User> find = tempelate.find(query, User.class);
            printUsers(find);
            
            
    //        查找lison1 和 lison12都评论过的user
    //        db.users.find({"comments.author":{"$all":["lison12","lison1"]}}).pretty()
    //         备注:跟数量有关,跟顺序无关;
    
            query = query(where("comments.author").all(Arrays.asList("lison1","lison12")));
            find = tempelate.find(query, User.class);
            printUsers(find);
        }
        
        
        
        @Test
        //(1)注意相关的实体bean要加上注解@document,@dbRef
        //(2)spring对dbRef进行了封装,发起了两次查询请求
        public void dbRefTest(){
            System.out.println("----------------------------");
            List<User> users = tempelate.findAll(User.class);
            System.out.println("----------------------------");
            System.out.println(users);
    //        System.out.println(users.get(0).getComments());
        }
    
        
        
        
        private void printUsers(List<User> find) {
            for (User user : find) {
                System.out.println(user);
            }
            System.out.println(find.size());
        }
        
        
        //---------------------------------------------------------
    
        
        
        
        //查找lison5评语为包含“苍老师”关键字的user($elemMatch查找符) 
    //    db.users.find({"comments":{"$elemMatch":{"author" : "lison5", "content" : { "$regex" : ".*苍老师.*"}}}})
    //备注:数组中对象数据要符合查询对象里面所有的字段,$全元素匹配,和顺序无关;
    
        @Test
        public void testObjArray3() throws ParseException {
    //        and(where("author").is("lison5"),where("content").regex(".*苍老师.*")))
            Criteria andOperator = new Criteria().andOperator(where("author").is("lison5"),where("content").regex(".*苍老师.*"));
            Query query = query(where("comments").elemMatch(andOperator));
            List<User> find = tempelate.find(query, User.class);
            printUsers(find);
        }
        
    
        @Test
        // db.users.find({"comments":{"$elemMatch":{"author" : "lison5","content" :
        // "lison是苍老师的小迷弟"}}}) .pretty()
        public void testElemMatch() {
            Query query = query(where("comments").elemMatch(where("author").is("lison5").and("content").is("lison是苍老师的小迷弟")));
            List<User> find = tempelate.find(query, User.class);
            System.out.println(find.size());
    
        }
    
        /**
         *             db.users.updateOne({"username":"lison",},
                        {"$push": {
                             "comments": {
                               $each: [{
                                        "author" : "james",
                                        "content" : "lison是个好老师!",
                                        "commentTime" : ISODate("2018-01-06T04:26:18.354Z")
                                    }
                                ],
                               $sort: {"commentTime":-1}
                             }}});
         */
        @Test
        // 新增评论时,使用$sort运算符进行排序,插入评论后,再按照评论时间降序排序
        public void demoStep1() {
            Query query = query(where("username").is("lison"));
            Comment comment = new Comment();
            comment.setAuthor("cang");
            comment.setCommentTime(new Date());
            comment.setContent("lison是我的粉丝");
    
            Update update = new Update();
            PushOperatorBuilder pob = update.push("comments");
            pob.each(comment);
            pob.sort(new Sort(new Sort.Order(Direction.DESC, "commentTime")));
            
            System.out.println("---------------");
            WriteResult updateFirst = tempelate.updateFirst(query, update,User.class);
            System.out.println("---------------");
            System.out.println(updateFirst.getN());
        }
    
        @Test
        // 查看人员时加载最新的三条评论;
        // db.users.find({"username":"lison"},{"comments":{"$slice":[0,3]}}).pretty()
        public void demoStep2() {
            //{"username":"lison"}
            Query query = query(where("username").is("lison"));
            //{"comments":{"$slice":[0,3]}
            query.fields().include("comments").slice("comments", 0, 3);
            System.out.println("---------------");
            List<User> find = tempelate.find(query, User.class);
            System.out.println("---------------");
            System.out.println(find);
        }
    
        @Test
        // 点击评论的下一页按钮,新加载三条评论
        // db.users.find({"username":"lison"},{"comments":{"$slice":[3,3]},"$id":1}).pretty();
        public void demoStep3() {
            Query query = query(where("username").is("lison"));
            query.fields().include("comments").slice("comments", 3, 3)
                    .include("id");
            System.out.println("---------------");
            List<User> find = tempelate.find(query, User.class);
            System.out.println("---------------");
            System.out.println(find);
        }
    
        
        /**
         * db.users.aggregate([{"$match":{"username":"lison"}},
                               {"$unwind":"$comments"},
                               {$sort:{"comments.commentTime":-1}},
                               {"$project":{"comments":1}},
                               {"$skip":6},
                               {"$limit":3}])
                               
         */
        // 如果有多种排序需求怎么处理,使用聚合
        @Test
        public void demoStep4() {
            Aggregation aggs = newAggregation(
                    match(where("username").is("lison")),
                    unwind("comments"),
                    sort(Direction.ASC, "comments.commentTime"),
                    project("comments"), 
                    skip(6), 
                    limit(3));
            System.out.println("---------------");
            AggregationResults<Object> aggregate = tempelate.aggregate(aggs, "users",    Object.class);
            System.out.println("---------------");
            List<Object> mappedResults = aggregate.getMappedResults();
            System.out.println(mappedResults.size());
    
        }
        
    
    
    
    }
    View Code

    MongoDB连接池配置

    聚合的理解

    聚合框架就是定义一个管道,管道里的每一步都为下一步输出数据数据

    常用的管道操作符

    $project:投影,指定输出文档中的字段;
    $match:用于过滤数据,只输出符合条件的文档。$match使用MongoDB的标准查询操作
    $limit:用来限制MongoDB聚合管道返回的文档数。
    $skip:在聚合管道中跳过指定数量的文档,并返回余下的文档。
    $unwind:将文档中的某一个数组类型字段拆分成多条,每条包含数组中的一个值。
    $group:将集合中的文档分组,可用于统计结果。
    $sort:将输入文档排序后输出。

    $group操作符

    $group:可以分组的数据执行如下的表达式计算:
    $sum:计算总和。
    $avg:计算平均值。
    $min:根据分组,获取集合中所有文档对应值得最小值。
    $max:根据分组,获取集合中所有文档对应值得最大值。

    聚合训练

    查询2015年4月3号之前,每个用户每个月消费的总金额,并按用户名进行排序:
    db.orders.aggregate([
    {"$match":{ "orderTime" : { "$lt" : new Date("2015-04-03T16:00:00.000Z")}}},
    {"$group":{"_id":{"useCode":"$useCode","month":{"$month":"$orderTime"}},"total":{"$sum":"$price"}}},
    {"$sort":{"_id":1}}
    ])

    package com.enjoylearning.mongo.entity;
    
    import java.math.BigDecimal;
    import java.util.Date;
    
    import org.bson.types.ObjectId;
    import org.springframework.data.annotation.Id;
    import org.springframework.data.mongodb.core.mapping.Document;
    
    @Document(collection = "orders")
    public class Order {
        @Id
        private String id;
    
        private String orderCode;
    
        private String useCode;
    
        private Date orderTime;
    
        private BigDecimal price;
        
        private String[] Auditors;
    
        public String getOrderCode() {
            return orderCode;
        }
    
        public void setOrderCode(String orderCode) {
            this.orderCode = orderCode;
        }
    
        public Date getOrderTime() {
            return orderTime;
        }
    
        public void setOrderTime(Date orderTime) {
            this.orderTime = orderTime;
        }
    
    
        public BigDecimal getPrice() {
            return price;
        }
    
        public void setPrice(BigDecimal price) {
            this.price = price;
        }
    
        public String getId() {
            return id;
        }
    
        public void setId(String id) {
            this.id = id;
        }
    
        public String getUseCode() {
            return useCode;
        }
    
        public void setUseCode(String useCode) {
            this.useCode = useCode;
        }
    
        public String[] getAuditors() {
            return Auditors;
        }
    
        public void setAuditors(String[] auditors) {
            Auditors = auditors;
        }
        
        
    
    }
    View Code
    package com.enjoylearning.lison.mongodb;
    
    
    import static org.springframework.data.mongodb.core.query.Criteria.where;
    import static org.springframework.data.mongodb.core.query.Query.query;
    import static org.springframework.data.mongodb.core.query.Update.update;
    
    import java.util.ArrayList;
    import java.util.HashSet;
    import java.util.List;
    import java.util.Random;
    import java.util.UUID;
    
    import javax.annotation.Resource;
    
    import org.bson.types.ObjectId;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.data.domain.Sort;
    import org.springframework.data.domain.Sort.Direction;
    import org.springframework.data.mongodb.core.FindAndModifyOptions;
    import org.springframework.data.mongodb.core.MongoOperations;
    import org.springframework.data.mongodb.core.query.Criteria;
    import org.springframework.data.mongodb.core.query.Query;
    import org.springframework.data.mongodb.core.query.Update;
    import org.springframework.data.mongodb.core.query.Update.PushOperatorBuilder;
    import org.springframework.test.context.ContextConfiguration;
    import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
    
    import com.enjoylearning.mongo.entity.Comment;
    import com.enjoylearning.mongo.entity.MyOrder;
    import com.enjoylearning.mongo.entity.Order;
    import com.enjoylearning.mongo.entity.User;
    import com.mongodb.WriteResult;
    
    
    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration("classpath:applicationContext.xml")
    public class GenarateOrdersTest {
    
        private static final Logger logger = LoggerFactory.getLogger(GenarateOrdersTest.class);
        
        @Resource
        private MongoOperations tempelate;
        
          //随机生成orderTest数据
        @Test
        public void batchInsertOrder() {
            String[] userCodes = new String[] { "james", "AV", "allen", "six",
                    "peter", "mark", "king", "zero", "lance", "deer", "lison" };
            String[] auditors = new String[] { "auditor1","auditor2","auditor3","auditor4","auditor5"};
            List<Order> list = new ArrayList<Order>();
            Random rand = new Random();
            for (int i = 0; i < 100000; i++) {
                Order order = new Order();
                int num = rand.nextInt(11);
                order.setUseCode(userCodes[num]);
                order.setOrderCode(UUID.randomUUID().toString());
                order.setOrderTime(RondomDateTest.randomDate("2015-01-01","2017-10-31"));
                order.setPrice(RondomDateTest.randomBigDecimal(10000, 1));
                int length = rand.nextInt(5)+1;
                String[] temp = new String[length];
                for (int j = 0; j < temp.length; j++) {
                    temp[j] = getFromArrays(temp,auditors,rand); 
                }
                order.setAuditors(temp);
                list.add(order);
            }
            tempelate.insertAll(list);
        }
    
    
        private String getFromArrays(String[] temp, String[] auditors, Random rand) {
            String ret = null;
            boolean test = true;
            while (test) {
                ret = auditors[rand.nextInt(5)];
                int i =0;
                for (String _temp : temp) {
                    i++;
                    if(ret.equals(_temp)){
                        break;
                    }
                }
                if(i==temp.length){
                    test=false;
                }
                
            }
            return ret;
    
        }
        
        
    }
    View Code

    查询2015年4月3号之前,每个审核员分别审批的订单总金额,按审核员名称进行排序:
    db.orders.aggregate([{"$match":{ "orderTime" : { "$lt" : new Date("2015-04-03T16:00:00.000Z")}}},
    {"$unwind":"$Auditors"},
    {"$group":{"_id":{"Auditors":"$Auditors"},"total":{"$sum":"$price"}}},
    {"$sort":{"_id":1}}])

    三、更新

    新增操作
    insertOne:插入单个文档
    insertMany:插入多个文档
    如果数据库和集合不存在,insert操作将自动创建;
    对于插入的数据,mongoDB自动生成 ObjectId 作为_id 字段(物理主键)

    删除操作
    deleteOne(query):删除单个文档
    deleteMany(query):删除多个文档
    删除操作是不会删除索引的,就算你把数据全部删除;

    更新操作概要

    update() 方法用于更新已存在的文档。语法格式如下:
    db.collection.update( <query>, <update>, { upsert: <boolean>, multi: <boolean>, writeConcern: <document> } )
    参数说明:
    query : update的查询条件,类似sql update查询内where后面的;
    update : update的对象和一些更新的操作符(如$,$inc...)等,也可以理解为sql update查询内set后面的
    upsert : 可选,这个参数的意思是,如果不存在update的记录,是否插入,true为插入,默认是false,不插入。
    multi : 可选,mongodb 默认是false,只更新找到的第一条记录,如果这个参数为true,就把按条件查出来多条记录全部更新。
    writeConcern :可选,写策略配置。

     upsert实例

    db.users.update({"username":"cang"},{"$set":{"age":18}},{"upsert":true})

    数据不存在,记录将被插入
    与插入操作相比,upsert插入的结果返回了_id字段

     更新选择器

    更新示例

    删除字段示例
    db.users.updateMany({"username":"lison"},{"$unset":{"country":"","age":""}})

    更新字段名称示例
    db.users.updateMany({"username":"lison"},{"$rename":{"lenght":"height", "username":"name"}})

    $each作用示例
    db.users.updateMany({ "username" : "james"}, { "$addToSet" : { "favorites.movies" : [ "小电影2 " , "小电影3"]}})
    db.users.updateMany({ "username" : "james"}, { "$addToSet" : { "favorites.movies" : { "$each" : [ "小电影2 " , "小电影3"]}}})


    删除字符串数组中元素示例
    db.users.updateMany({ "username" : "james"}, { "$pull" : { "favorites.movies" : [ "小电影2 " , "小电影3"]}})
    db.users.updateMany({ "username" : "james"}, { "$pullAll" : { "favorites.movies" : [ "小电影2 " , "小电影3"]}})

    向对象数组中插入元素
    给james老师增加一条评论($push,默认放在数组最后)
    db.users.updateOne({"username":"james"},{"$push":{"comments":{"author":"lison23","content":"ydddyyytttt","commentTime":ISODate("2019-01-06T00:00:00")}}})
    给james老师批量新增两条评论($push,$each)
    db.users.updateOne({"username":"james"},
    {"$push":{"comments":
    {"$each":[{"author":"lison22","content":"yyyytttt","commentTime":ISODate("2019-02-06T00:00:00")},
    {"author":"lison23","content":"ydddyyytttt","commentTime":ISODate("2019-03-06T00:00:00")}]}}})

    给james老师批量新增两条评论并对数组进行排序($push,$each,$sort)
    db.users.updateOne({"username":"james"},
    {"$push": {"comments":
    {"$each":[ {"author":"lison22","content":"yyyytttt","commentTime":ISODate("2019-04-06T00:00:00")},
    {"author":"lison23","content":"ydddyyytttt","commentTime":ISODate("2019-05-06T00:00:00")} ],
    $sort: {"commentTime":-1} } } })

    删除对象数组中元素示
    删除lison22对james的所有评论 (批量删除)
    db.users.update({"username":"james"},
    {"$pull":{"comments":{"author":"lison22"}}})
    删除lison5对lison评语为"lison是苍老师的小迷弟"的评论
    db.users.update({"username":"lison"},
    {"$pull":{"comments":{"author":"lison5",
    "content":"lison是苍老师的小迷弟"}}})

    更新对象数组中元素,$符号示例
    db.users.updateMany({"username":"james","comments.author":"lison1"},
    {“$set”:{“comments.$.content":"xxoo",
    "comments.$.author":"lison10" }})
    含义:精确修改某人某一条精确的评论,如果有多个符合条件的数据,则修改第一条数据。无法批量修改数组元素,也无法对数组元素做批量更新

    更新的注意点

    mongodb的更新都是原子的,mongodb所有的写操作都是有锁的。mongoDB 2.2之前锁级别为实例级别,mongoDB 2.2到3.2之前的版本锁级别为数据库级别,mongoDB 3.2以后,WiredTiger的锁级别是文档级别;
    findAndModify命令:在同一往返过程中原子更新文档并返回它;

    findandModify命令示例

    常规的update的方法不能返回更新后的数据
    db.fam.update({"name":"morris1"},{"$inc":{"age":1}})
    使用findandModify方法在修改数据同时返回更新前的数据或更新后的数据
    db.fam.findAndModify({query:{name:'morris1'},
    update:{$inc:{age:1}},
    'new':true});

    Java示例代码

    原生驱动的实现

    package com.enjoylearning.lison.mongodb;
    
    import static com.mongodb.client.model.Filters.*;
    import static com.mongodb.client.model.Projections.*;
    import static com.mongodb.client.model.Sorts.*;
    import static com.mongodb.client.model.Aggregates.*;
    import static com.mongodb.client.model.Updates.*;
    
    import java.text.ParseException;
    import java.text.SimpleDateFormat;
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.Date;
    import java.util.List;
    
    import javax.annotation.Resource;
    
    import org.bson.BSON;
    import org.bson.BsonDocument;
    import org.bson.Document;
    import org.bson.codecs.configuration.CodecRegistries;
    import org.bson.codecs.configuration.CodecRegistry;
    import org.bson.codecs.pojo.PojoCodecProvider;
    import org.bson.conversions.Bson;
    import org.bson.types.ObjectId;
    import org.junit.Before;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.test.context.ContextConfiguration;
    import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
    
    import com.mongodb.Block;
    import com.mongodb.MongoClient;
    import com.mongodb.MongoClientOptions;
    import com.mongodb.ServerAddress;
    import com.mongodb.WriteConcern;
    import com.mongodb.client.AggregateIterable;
    import com.mongodb.client.FindIterable;
    import com.mongodb.client.MongoCollection;
    import com.mongodb.client.MongoDatabase;
    import com.mongodb.client.model.Filters;
    import com.mongodb.client.model.FindOneAndUpdateOptions;
    import com.mongodb.client.model.Projections;
    import com.mongodb.client.model.PushOptions;
    import com.mongodb.client.model.ReturnDocument;
    import com.mongodb.client.model.UpdateOptions;
    import com.mongodb.client.model.Updates;
    import com.mongodb.client.result.UpdateResult;
    import com.mongodb.operation.OrderBy;
    
    
    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration("classpath:applicationContext.xml")
    public class JavaUpdateObjArray {
    
        private static final Logger logger = LoggerFactory.getLogger(JavaUpdateObjArray.class);
        
        private MongoDatabase db;
    
    
        private MongoCollection<Document> collection;
        
        @Resource(name="mongo")
        private MongoClient client;
        
        
        @Before
        public void init(){
                db = client.getDatabase("lison");
                collection=db.getCollection("users");
        }
        
        
        
        //--------------------------------------upsert demo--------------------------------------------------------------
        
        //测试upsert
        //db.users.update({"username":"cang"},{"$set":{"age":18}},{"upsert":true})
        @Test
        public void upsertTest(){
            Bson filter = eq("username","cang");
            Bson update = set("age", 18);
            UpdateOptions upsert = new UpdateOptions().upsert(true);
            UpdateResult updateOne = collection.updateOne(filter, update,upsert);
            System.out.println(updateOne.getModifiedCount());
            System.out.println(updateOne.getUpsertedId());
            
        }
        
        //测试unset,删除字段示例
        //db.users.updateMany({"username":"lison"},{"$unset":{"country":"","age":""}})
        @Test
        public void unsetTest(){
            Bson filter = eq("username","lison");
            Bson country = unset("country");
            Bson age = unset("age");
            Bson update = combine(country,age);
            UpdateResult updateOne = collection.updateMany(filter, update);
            System.out.println(updateOne.getModifiedCount());
            System.out.println(updateOne.getUpsertedId());
            
        }
        
        //测试rename,更新字段名称示例
        //db.users.updateMany({"username":"lison"},{"$rename":{"lenght":"height", "username":"name"}})
    
        @Test
        public void renameTest(){
            Bson filter = eq("username","lison");
            Bson rename1 = rename("lenght", "height");
            Bson rename2 = rename("username", "name");
            Bson update = combine(rename1,rename2);
            UpdateResult updateOne = collection.updateMany(filter, update);
            System.out.println(updateOne.getModifiedCount());
            System.out.println(updateOne.getUpsertedId());
            
        }
        
        
        //测试pull pullAll,删除字符串数组中元素示例
    //    db.users.updateMany({ "username" : "james"}, { "$pull" : { "favorites.movies" : [ "小电影2 " , "小电影3"]}})
    //    db.users.updateMany({ "username" : "james"}, { "$pullAll" : { "favorites.movies" : [ "小电影2 " , "小电影3"]}})
    
        @Test
        public void pullAllTest(){
            Bson filter = eq("username","james");
            Bson pull = pull("favorites.movies", Arrays.asList("小电影2 " , "小电影3"));
            UpdateResult updateOne = collection.updateMany(filter, pull);
            System.out.println(updateOne.getModifiedCount());
            System.out.println(updateOne.getUpsertedId());
            
            Bson pullAll = pullAll("favorites.movies", Arrays.asList("小电影2 " , "小电影3"));
            updateOne = collection.updateMany(filter, pullAll);
            System.out.println(updateOne.getModifiedCount());
            System.out.println(updateOne.getUpsertedId());
        }
    
        
        
        
        //--------------------------------------insert demo--------------------------------------------------------------
        
        //给james老师增加一条评论($push)
        //db.users.updateOne({"username":"james"},
    //                         {"$push":{"comments":{"author":"lison23",
    //                                     "content":"ydddyyytttt",
    //                                     "commentTime":ISODate("2019-01-06T00:00:00")}}})
    
        @Test
        public void addOneComment(){
            Document comment = new Document().append("author", "lison23")
                                            .append("content", "ydddyyytttt")
                                            .append("commentTime", getDate("2019-01-06"));
            Bson filter = eq("username","james");
            Bson update = push("comments",comment);
            UpdateResult updateOne = collection.updateOne(filter, update);
            System.out.println(updateOne.getModifiedCount());
            
        }
        
        
    
    
    
    
        //    给james老师批量新增两条评论($push,$each)
    //    db.users.updateOne({"username":"james"},     
    //               {"$push":{"comments":
    //                          {"$each":[{"author":"lison22","content":"yyyytttt","commentTime":ISODate("2019-02-06T00:00:00")},
    //                                    {"author":"lison23","content":"ydddyyytttt","commentTime":ISODate("2019-03-06T00:00:00")}]}}})
    
        @Test
        public void addManyComment(){
            Document comment1 = new Document().append("author", "lison33")
                                            .append("content", "lison33lison33")
                                            .append("commentTime", getDate("2019-02-06"));
            Document comment2 = new Document().append("author", "lison44")
                                            .append("content", "lison44lison44")
                                            .append("commentTime", getDate("2019-03-06"));
            
            Bson filter = eq("username","james");
            Bson pushEach = pushEach("comments",Arrays.asList(comment1,comment2));
            UpdateResult updateOne = collection.updateOne(filter, pushEach);
            System.out.println(updateOne.getModifiedCount());
            
        }
        
        
    //    给james老师批量新增两条评论并对数组进行排序($push,$eachm,$sort)
    //    db.users.updateOne({"username":"james"}, 
    //              {"$push": {"comments":
    //                        {"$each":[ {"author":"lison22","content":"yyyytttt","commentTime":ISODate("2019-04-06T00:00:00")},
    //                                   {"author":"lison23","content":"ydddyyytttt","commentTime":ISODate("2019-05-06T00:00:00")} ], 
    //                          $sort: {"commentTime":-1} } } })
    
        @Test
        public void addManySortComment(){
            Document comment1 = new Document().append("author", "lison00")
                                            .append("content", "lison00lison00")
                                            .append("commentTime", getDate("2019-04-06"));
            Document comment2 = new Document().append("author", "lison01")
                                            .append("content", "lison01lison01")
                                            .append("commentTime", getDate("2019-05-06"));
            
            Bson filter = eq("username","james");
            
            Document sortDoc = new Document().append("commentTime", -1);
            PushOptions pushOption = new PushOptions().sortDocument(sortDoc);
            
            Bson pushEach = pushEach("comments",Arrays.asList(comment1,comment2),pushOption);
            
            UpdateResult updateOne = collection.updateOne(filter, pushEach);
            System.out.println(updateOne.getModifiedCount());
            
        }
     
        //--------------------------------------delete demo--------------------------------------------------------------
     
    //    删除lison1对james的所有评论 (批量删除)
    //    db.users.update({"username":“james"},
    //                               {"$pull":{"comments":{"author":"lison33"}}})
    
        @Test
        public void deleteByAuthorComment(){
            Document comment = new Document().append("author", "lison33");
            Bson filter = eq("username","james");
            Bson update = pull("comments",comment);
            UpdateResult updateOne = collection.updateOne(filter, update);
            System.out.println(updateOne.getModifiedCount());
        }
        
        
    //    删除lison5对lison评语为“lison是苍老师的小迷弟”的评论(精确删除)
    //    db.users.update({"username":"lison"},
    //            {"$pull":{"comments":{"author":"lison5",
    //                                  "content":"lison是苍老师的小迷弟"}}})
        @Test
        public void deleteByAuthorContentComment(){
            Document comment = new Document().append("author", "lison5")
                                             .append("content", "lison是苍老师的小迷弟");
            Bson filter = eq("username","lison");
            Bson update = pull("comments",comment);
            UpdateResult updateOne = collection.updateOne(filter, update);
            System.out.println(updateOne.getModifiedCount());
        }
        
        //--------------------------------------update demo--------------------------------------------------------------
    //    db.users.updateMany({"username":"james","comments.author":"lison01"},
    //            {"$set":{"comments.$.content":"xxoo",
    //                        "comments.$.author":"lison10" }})
    //        含义:精确修改某人某一条精确的评论,如果有多个符合条件的数据,则修改最后一条数据。无法批量修改数组元素
      @Test
      public void updateOneComment(){
              Bson filter = and(eq("username","james"),eq("comments.author","lison01"));
              Bson updateContent = set("comments.$.content","xxoo");
              Bson updateAuthor = set("comments.$.author","lison10");
              Bson update = combine(updateContent,updateAuthor);
              UpdateResult updateOne = collection.updateOne(filter, update);
              System.out.println(updateOne.getModifiedCount());
          
      }
      
      
    //--------------------------------------findandModify demo--------------------------------------------------------------
      //使用findandModify方法在修改数据同时返回更新前的数据或更新后的数据
    //db.fam.findAndModify({query:{name:'morris1'}, 
    //    update:{$inc:{age:1}}, 
    //    'new':true});
    
      @Test
      public void findAndModifyTest(){
          Bson filter = eq("name","morris1");
          Bson update = inc("age",1);
    //      //实例化findAndModify的配置选项
          FindOneAndUpdateOptions fauo = new FindOneAndUpdateOptions();
    //      //配置"new":true
          fauo.returnDocument(ReturnDocument.AFTER);//
          MongoCollection<Document> numCollection = db.getCollection("fam");
          Document ret = numCollection.findOneAndUpdate(filter, update,fauo);
          System.out.println(ret.toJson());
      }
      
      
      
      private Date getDate(String string) {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            
            Date parse=null;
            try {
                parse = sdf.parse(string);
            } catch (ParseException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            return parse;
        }
      
      
      
    }
    View Code

    Spring data的实现

    package com.enjoylearning.lison.mongodb;
    
    
    import static org.springframework.data.mongodb.core.query.Criteria.where;
    import static org.springframework.data.mongodb.core.query.Query.query;
    import static org.springframework.data.mongodb.core.query.Update.update;
    
    import java.text.ParseException;
    import java.text.SimpleDateFormat;
    import java.util.Arrays;
    import java.util.Date;
    
    import javax.annotation.Resource;
    
    import org.bson.types.ObjectId;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.data.domain.Sort;
    import org.springframework.data.domain.Sort.Direction;
    import org.springframework.data.mongodb.core.FindAndModifyOptions;
    import org.springframework.data.mongodb.core.MongoOperations;
    import org.springframework.data.mongodb.core.query.Criteria;
    import org.springframework.data.mongodb.core.query.Query;
    import org.springframework.data.mongodb.core.query.Update;
    import org.springframework.data.mongodb.core.query.Update.PushOperatorBuilder;
    import org.springframework.test.context.ContextConfiguration;
    import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
    
    import com.enjoylearning.mongo.entity.Comment;
    import com.enjoylearning.mongo.entity.Doc;
    import com.enjoylearning.mongo.entity.MyOrder;
    import com.enjoylearning.mongo.entity.User;
    import com.mongodb.WriteResult;
    
    
    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration("classpath:applicationContext.xml")
    public class SpringUpdateObjArray {
    
        private static final Logger logger = LoggerFactory.getLogger(SpringUpdateObjArray.class);
        
        @Resource
        private MongoOperations tempelate;
        
        
        
        //--------------------------------------upsert demo--------------------------------------------------------------
        
        //测试upsert
        //db.users.update({"username":"cang"},{"$set":{"age":18}},{"upsert":true})
        @Test
        public void upsertTest(){
            Query query = query(Criteria.where("username").is("cang"));
            Update set = new Update().set("age", 18);
            WriteResult upsert = tempelate.upsert(query, set, User.class);
            System.out.println(upsert.getN());
            System.out.println(upsert.getUpsertedId());
            
        }
        
        
        
        //测试unset,删除字段示例
        //db.users.updateMany({"username":"lison"},{"$unset":{"country":"","age":""}})
        @Test
        public void unsetTest(){
            Query query = query(Criteria.where("username").is("lison"));
            Update unset = new Update().unset("country").unset("age");
            
            WriteResult upsert = tempelate.updateMulti(query, unset, User.class);
            System.out.println(upsert.getN());
        }
        
        //测试rename,更新字段名称示例
        //db.users.updateMany({"username":"lison"},{"$rename":{"lenght":"height", "username":"name"}})
    
        @Test
        public void renameTest(){
            Query query = query(Criteria.where("username").is("lison"));
            Update rename = new Update().rename("lenght", "height").rename("username", "name");
            WriteResult upsert = tempelate.updateMulti(query, rename, User.class);
            System.out.println(upsert.getN());
    
        }
        
        
        //测试pull pullAll,删除字符串数组中元素示例
    //    db.users.updateMany({ "username" : "james"}, { "$pull" : { "favorites.movies" : [ "小电影2 " , "小电影3"]}})
    //    db.users.updateMany({ "username" : "james"}, { "$pullAll" : { "favorites.movies" : [ "小电影2 " , "小电影3"]}})
    
        @Test
        public void pullAllTest(){
            
            Query query = query(Criteria.where("username").is("james"));
            Update pull = new Update().pull("favorites.movies", Arrays.asList("小电影2 " , "小电影3"));
            WriteResult upsert = tempelate.updateMulti(query, pull, User.class);
            System.out.println(upsert.getN());
            
            
            
            query = query(Criteria.where("username").is("james"));
            Update pullAll = new Update().pullAll("favorites.movies", new String[]{"小电影2 " , "小电影3"});
            upsert = tempelate.updateMulti(query, pullAll, User.class);
            System.out.println(upsert.getN());
        }
    
    
        
        
        
        //--------------------------------------insert demo--------------------------------------------------------------
        
        
        //给james老师增加一条评论($push)
        //db.users.updateOne({"username":"james"},
    //                         {"$push":{"comments":{"author":"lison23",
    //                                     "content":"ydddyyytttt",
    //                                     "commentTime":ISODate("2019-01-06T00:00:00")}}})
        @Test
        public void addOneComment(){
            Query query = query(Criteria.where("username").is("james"));
            Comment comment = new Comment();
            comment.setAuthor("lison23");
            comment.setContent("ydddyyytttt");
            comment.setCommentTime(getDate("2019-01-06"));
            Update push = new Update().push("comments", comment);
            WriteResult updateFirst = tempelate.updateFirst(query, push, User.class);
            System.out.println(updateFirst.getN());
        }
        
        
        //    给james老师批量新增两条评论($push,$each)
    //  db.users.updateOne({"username":"james"},     
    //             {"$push":{"comments":
    //                        {"$each":[{"author":"lison22","content":"yyyytttt","commentTime":ISODate("2019-02-06T00:00:00")},
    //                                  {"author":"lison23","content":"ydddyyytttt","commentTime":ISODate("2019-03-06T00:00:00")}]}}})
        @Test
        public void addManyComment(){
            Query query = query(Criteria.where("username").is("james"));
            Comment comment1 = new Comment();
            comment1.setAuthor("lison55");
            comment1.setContent("lison55lison55");
            comment1.setCommentTime(getDate("2019-02-06"));
            Comment comment2 = new Comment();
            comment2.setAuthor("lison66");
            comment2.setContent("lison66lison66");
            comment2.setCommentTime(getDate("2019-03-06"));
            Update push = new Update().pushAll("comments", new Comment[]{comment1,comment2});
            WriteResult updateFirst = tempelate.updateFirst(query, push, User.class);
            System.out.println(updateFirst.getN());       
        }
        
    //  给james老师批量新增两条评论并对数组进行排序($push,$eachm,$sort)
    //  db.users.updateOne({"username":"james"}, 
    //            {"$push": {"comments":
    //                      {"$each":[ {"author":"lison22","content":"yyyytttt","commentTime":ISODate("2019-04-06T00:00:00")},
    //                                 {"author":"lison23","content":"ydddyyytttt","commentTime":ISODate("2019-05-06T00:00:00")} ], 
    //                        $sort: {"commentTime":-1} } } })
        @Test
        public void addManySortComment(){
            Query query = query(Criteria.where("username").is("james"));
            Comment comment1 = new Comment();
            comment1.setAuthor("lison77");
            comment1.setContent("lison55lison55");
            comment1.setCommentTime(getDate("2019-04-06"));
            Comment comment2 = new Comment();
            comment2.setAuthor("lison88");
            comment2.setContent("lison66lison66");
            comment2.setCommentTime(getDate("2019-05-06"));
            
            
            Update update = new Update();
            PushOperatorBuilder pob = update.push("comments");
            pob.each(comment1,comment2);
            pob.sort(new Sort(new Sort.Order(Direction.DESC, "commentTime")));
            
            System.out.println("---------------");
            WriteResult updateFirst = tempelate.updateFirst(query, update,User.class);
            System.out.println(updateFirst.getN());   
        }
     
        //--------------------------------------delete demo--------------------------------------------------------------
     
    //    删除lison1对james的所有评论 (批量删除)
    //    db.users.update({"username":“james"},
    //                               {"$pull":{"comments":{"author":"lison23"}}})
    
        @Test
        public void deleteByAuthorComment(){
            Query query = query(Criteria.where("username").is("james"));
            
            Comment comment1 = new Comment();
            comment1.setAuthor("lison55");
            Update pull = new Update().pull("comments",comment1);
            WriteResult updateFirst = tempelate.updateFirst(query, pull, User.class);
            System.out.println(updateFirst.getN());       
        }
        
        
    //    删除lison5对lison评语为“lison是苍老师的小迷弟”的评论(精确删除)
    //    db.users.update({"username":"lison"},
    //            {"$pull":{"comments":{"author":"lison5",
    //                                  "content":"lison是苍老师的小迷弟"}}})
        @Test
        public void deleteByAuthorContentComment(){
            Query query = query(Criteria.where("username").is("lison"));
            Comment comment1 = new Comment();
            comment1.setAuthor("lison5");
            comment1.setContent("lison是苍老师的小迷弟");
            Update pull = new Update().pull("comments",comment1);
            WriteResult updateFirst = tempelate.updateFirst(query, pull, User.class);
            System.out.println(updateFirst.getN());  
        }
        
        //--------------------------------------update demo--------------------------------------------------------------
    //    db.users.updateMany({"username":"james","comments.author":"lison1"},
    //            {"$set":{"comments.$.content":"xxoo",
    //                        "comments.$.author":"lison10" }})
    //        含义:精确修改某人某一条精确的评论,如果有多个符合条件的数据,则修改最后一条数据。无法批量修改数组元素
      @Test
      public void updateOneComment(){
              Query query = query(where("username").is("lison").and("comments.author").is("lison4"));
              Update update = update("comments.$.content","xxoo").set("comments.$.author","lison11");
            WriteResult updateFirst = tempelate.updateFirst(query, update, User.class);
            System.out.println(updateFirst.getN());  
      }
    
    //--------------------------------------findandModify demo--------------------------------------------------------------
    
      
      
      //使用findandModify方法在修改数据同时返回更新前的数据或更新后的数据
    //db.fam.findAndModify({query:{name:'morris1'}, 
    //    update:{$inc:{age:1}}, 
    //    'new':true});
      
        @Test
        public void findAndModifyTest(){
            Query query = query(where("name").is("morris1"));
            Update update = new Update().inc("age", 1);
            FindAndModifyOptions famo = FindAndModifyOptions.options().returnNew(true);
            
            Doc doc = tempelate.findAndModify(query, update,famo, Doc.class);
            System.out.println(doc.toString());
        }
        
        
        
        
        
        
          private Date getDate(String string) {
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                
                Date parse=null;
                try {
                    parse = sdf.parse(string);
                } catch (ParseException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                return parse;
            }
          
        
        
    }
    View Code

    四、其他命令

    其他常用命令

    show dbs :显示数据库列表
    show collections :显示集合列表
    db : 显示当前数据库
    db.stats() :显示数据库信息
    db.serverStatus() : 查看服务器状态
    db.dropDatabase():删除数据库
    db.help(),db.collection.help():内置帮助,显示各种方法的说明;
    db.users.find().size():获取查询集合的数量;
    db.users.drop():删除集合;

  • 相关阅读:
    模拟器安装.apk包_夜神模拟器
    SDK安装报错_2019
    Jenkins安装插件方法
    Jenkins安装
    Python项目第三方库安装_pip freeze命令
    深入理解Java虚拟机—内存分配
    深入理解Java虚拟机—垃圾回收 下
    深入理解Java虚拟机—垃圾回收 上
    深入理解Java虚拟机—OutOfMemoryError异常
    深入理解Java虚拟机—Java内存区域
  • 原文地址:https://www.cnblogs.com/skorzeny/p/10473975.html
Copyright © 2020-2023  润新知