当前位置:   article > 正文

java操作mongodb源码_java mongocursor 查询源码分析

java mongocursor 查询源码分析

案例一:MongoClient最简单操作

1、优缺点

  • 优点:简单,快速测试实现
  • 缺点:不适合项目整合使用

2、添加依赖

<dependency>
    <groupId>org.mongodb</groupId>
    <artifactId>mongo-java-driver</artifactId>
    <version>3.12.10</version>
</dependency>
  • 1
  • 2
  • 3
  • 4
  • 5

3、源码

package com.detail.util;
import java.util.ArrayList;
import java.util.List;

import org.bson.Document;
import org.bson.conversions.Bson;

import com.mongodb.MongoClient;
import com.mongodb.MongoCredential;
import com.mongodb.ServerAddress;
import com.mongodb.client.FindIterable;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoCursor;
import com.mongodb.client.MongoDatabase;
import com.mongodb.client.model.Filters;
 
//mongodb 连接数据库工具类
public class MongoDBUtil {
    //不通过认证获取连接数据库对象
    public static MongoDatabase getConnect(){
        //连接到 mongodb 服务
        MongoClient mongoClient = new MongoClient("服务器ip", 27017);
 
        //连接到数据库
        MongoDatabase mongoDatabase = mongoClient.getDatabase("test");
 
        //返回连接数据库对象
        return mongoDatabase;
    }
 
    //需要密码认证方式连接
    public static MongoDatabase getAuthConnect(){
        List<ServerAddress> adds = new ArrayList<>();
        //ServerAddress()两个参数分别为 服务器地址 和 端口
        ServerAddress serverAddress = new ServerAddress("服务器ip", 27017);
        adds.add(serverAddress);
        
        List<MongoCredential> credentials = new ArrayList<>();
        //MongoCredential.createScramSha1Credential()三个参数分别为 用户名 数据库名称 密码
        MongoCredential mongoCredential = MongoCredential.createScramSha1Credential("root", "test", "root".toCharArray());
        credentials.add(mongoCredential);
        
        //通过连接认证获取MongoDB连接
        MongoClient mongoClient = new MongoClient(adds, credentials);
 
        //连接到数据库
        MongoDatabase mongoDatabase = mongoClient.getDatabase("test");
 
        //返回连接数据库对象
        return mongoDatabase;
    }
    //插入一个文档
    public void insertOneTest(){
        //获取数据库连接对象
        MongoDatabase mongoDatabase = MongoDBUtil.getConnect();
        //获取集合
        MongoCollection<Document> collection = mongoDatabase.getCollection("user");
        //要插入的数据
        Document document = new Document("name","张三")
                                .append("sex", "男")
                                .append("age", 18);
        //插入一个文档
        collection.insertOne(document);
    }
  //插入多个文档
    public void insertManyTest(){
        //获取数据库连接对象
        MongoDatabase mongoDatabase = MongoDBUtil.getConnect();
        //获取集合
        MongoCollection<Document> collection = mongoDatabase.getCollection("user");
        //要插入的数据
        List<Document> list = new ArrayList<>();
        for(int i = 1; i <= 3; i++) {
            Document document = new Document("name", "张三")
                    .append("sex", "男")
                    .append("age", 18);
            list.add(document);
        }
        //插入多个文档
        collection.insertMany(list);
    }
  //删除与筛选器匹配的单个文档
    public void deleteOneTest(){
        //获取数据库连接对象
        MongoDatabase mongoDatabase = MongoDBUtil.getConnect();
        //获取集合
        MongoCollection<Document> collection = mongoDatabase.getCollection("user");
        //申明删除条件
        Bson filter = Filters.eq("age",18);
        //删除与筛选器匹配的单个文档
        collection.deleteOne(filter);
    }
  //删除与筛选器匹配的所有文档
    public void deleteManyTest(){
        //获取数据库连接对象
        MongoDatabase mongoDatabase = MongoDBUtil.getConnect();
        //获取集合
        MongoCollection<Document> collection = mongoDatabase.getCollection("user");
        //申明删除条件
        Bson filter = Filters.eq("age",18);
        //删除与筛选器匹配的所有文档
        collection.deleteMany(filter);
    }
  //修改单个文档
    public void updateOneTest(){
        //获取数据库连接对象
        MongoDatabase mongoDatabase = MongoDBUtil.getConnect();
        //获取集合
        MongoCollection<Document> collection = mongoDatabase.getCollection("user");
        //修改过滤器
        Bson filter = Filters.eq("name", "张三");
        //指定修改的更新文档
        Document document = new Document("$set", new Document("age", 100));
        //修改单个文档
        collection.updateOne(filter, document);
    }
  //修改多个文档
    public void updateManyTest(){
        //获取数据库连接对象
        MongoDatabase mongoDatabase = MongoDBUtil.getConnect();
        //获取集合
        MongoCollection<Document> collection = mongoDatabase.getCollection("user");
        //修改过滤器
        Bson filter = Filters.eq("name", "张三");
        //指定修改的更新文档
        Document document = new Document("$set", new Document("age", 100));
        //修改多个文档
        collection.updateMany(filter, document);
    }
  //查找集合中的所有文档
    public void findTest(){
        //获取数据库连接对象
//        MongoDatabase mongoDatabase = MongoDBUtil.getAuthConnect();
        MongoDatabase mongoDatabase = MongoDBUtil.getConnect();
        //获取集合
        MongoCollection<Document> collection = mongoDatabase.getCollection("customer");
        //查找集合中的所有文档
        FindIterable findIterable = collection.find();
        MongoCursor cursor = findIterable.iterator();
        while (cursor.hasNext()) {
            System.out.println(cursor.next());
        }
    }
  //指定查询过滤器查询
    public void FilterfindTest(){
        //获取数据库连接对象
        MongoDatabase mongoDatabase = MongoDBUtil.getConnect();
        //获取集合
        MongoCollection<Document> collection = mongoDatabase.getCollection("user");
        //指定查询过滤器
        Bson filter = Filters.eq("name", "张三");
        //指定查询过滤器查询
        FindIterable findIterable = collection.find(filter);
        MongoCursor cursor = findIterable.iterator();
        while (cursor.hasNext()) {
            System.out.println(cursor.next());
        }
    }
  //取出查询到的第一个文档
    public void findFirstTest(){
        //获取数据库连接对象
        MongoDatabase mongoDatabase = MongoDBUtil.getConnect();
        //获取集合
        MongoCollection<Document> collection = mongoDatabase.getCollection("user");
        //查找集合中的所有文档
        FindIterable findIterable = collection.find();
        //取出查询到的第一个文档
        Document document = (Document) findIterable.first();
        //打印输出
        System.out.println(document);
    }
    public static void main(String[] args) {
    	MongoDBUtil mongodb = new MongoDBUtil();
    	mongodb.findTest();
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176

案例二:继承MongoRepository

懒得搭建,需要的话进扣扣裙索要,783092701

1、优缺点

  • 优点:适合springboot项目整合,分层操作
  • 缺点:不支持过滤条件分组。即不支持过滤条件用 or(或) 来连接,所有的过滤条件,都是简单一层的用 and(并且) 连接不支持两个值的范围查询,如时间范围的查询

2、接口类继承MongoRepository

package com.yhzq.dao.repository;

import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.stereotype.Component;

import com.yhzq.dao.entity.Customer;

import java.util.List;
/**
 * <p>Title: 客户数据访问服务</p>
 * <p>Description:抽象出接口层,目的是为了自定义规范;
 * 				     并且未声明的,使用时,父类的也能直接使用 </p>
 * @author wangmoumo
 * @myblog www.681vip.com
 * @date 2022年10月18日
 */
public interface BaseRepository extends MongoRepository<Customer, String> {

	Customer findByFirstName(String firstName);

    List<Customer> findByLastName(String lastName);

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

3、service类注入接口BaseRepository

package com.yhzq.service;

import org.springframework.data.domain.Example;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;

import com.yhzq.dao.entity.Customer;
import com.yhzq.dao.repository.BaseRepository;

import javax.annotation.Resource;
import java.util.List;
/**
 * <p>Title: CustomerService.java</p>
 * <p>Description: service操作mongodb</p>
 * @author wangmoumo
 * @myblog www.681vip.com
 * @date 2022年10月18日
 */
@Service
public class CustomerService{
    @Resource
    private BaseRepository repository;
    /**
     * 保存客户
     * @param customer 客户
     * 第一种使用save的方式修改,一般这种只能修改单个。
     * 这种修改的方式是通过id去修改,如果id不存在就新增一个,
     * 存在就修改为新传入的数据
     */
    public List<Customer> saveAll(Iterable<Customer> iterable) {
    	return repository.saveAll(iterable);
    }

    /**
     * 保存客户
     * @param customer 客户
     */
    public Customer save(Customer customer) {
        Customer save = repository.save(customer);
        return save;
    }
    /**
     * 删除所有的客户
     */
    public void deleteAll() {
        repository.deleteAll();
    }
    /**
     * 删除所有的客户
     */
    public void deleteAll(Customer customer) {
        repository.delete(customer);
    }
    /**
     * 删除所有的客户
     */
    public void deleteAll(Iterable<? extends Customer> entities) {
        repository.deleteAll(entities);
    }
    /**
     * 删除所有的客户
     */
    public void deleteById(String id) {
        repository.deleteById(id);
    }
    
    /**
     * 查询所有客户列表
     * @return 客户列表
     */
    public List<Customer> findAll() {
        return repository.findAll();
    }
    /**
     * 查询所有客户列表
     * @return 客户列表
     */
    public Iterable<Customer> findAll(Sort sort) {
        return repository.findAll(sort);
    }
    /**
     * 查询所有客户列表
     * @return 客户列表
     */
    public Iterable<Customer> findAll(Example<Customer> example) {
        return repository.findAll(example);
    }

    /**
     * 查询所有客户列表
     * @return 客户列表
     */
    public Iterable<Customer> findAllById(Iterable<String> ids) {
        return repository.findAllById(ids);
    }


    /**
     * 通过名查找某个客户
     * @param firstName
     * @return
     */
    public Customer findByFirstName(String firstName) {
        return repository.findByFirstName(firstName);
    }

    /**
     * 通过姓查找客户列表
     * @param lastName
     * @return
     */
    public List<Customer> findByLastName(String lastName) {
        return repository.findByLastName(lastName);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115

4、controller类注入service类

package com.yhzq.controller;

import java.util.List;

import javax.annotation.Resource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.yhzq.dao.entity.Customer;
import com.yhzq.service.CustomerService;

@RestController
public class CustomerController{
	private static final Logger log = LoggerFactory.getLogger(CustomerController.class);
	
	@Resource
    private CustomerService service;
	
	
	@RequestMapping("/customer")
	public Customer save(){
		Customer customer = new Customer("wang","baoluo");
        Customer save = service.save(customer);
        log.info("save:"+save);
        return save;
    }
	
	@RequestMapping("/list")
	public List<Customer> findAll() {
		List<Customer> findAll = service.findAll();
		log.info("findAll:"+findAll);
		return findAll;
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38

案例三:使用MongoTemplate

懒得搭建,需要的话进扣扣裙索要,783092701

1、优缺点

  • 优点:擅长复杂查询,条件查询,聚合查询
  • 缺点:不支持返回固定字段

2、MongoTemplate结合Query

2.1 实现一:使用Criteria封装增删改查条件

在这里插入图片描述

2.1.1 Dao注入mongotemplate

package com.example.dao;

import com.example.entity.MongodbTest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
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.stereotype.Component;

/**
 * create by wbl
 * 2023/02/08
 */
@Component
public class MongodbTestDao {
    @Autowired
    private MongoTemplate mongoTemplate;

    /**
     * 创建对象
     * @param test
     */
    public void save(MongodbTest test) {
        mongoTemplate.insert(test);
    }

    /**
     * 根据名字去查询对象
     * @param name
     * @return
     */
    public MongodbTest findOne(String name) {
        Query query = new Query(Criteria.where("name").is(name));
        MongodbTest mgt = mongoTemplate.findOne(query,MongodbTest.class);
        return mgt;
    }

    /**
     * 修改对象
     * @param test
     */
    public void updateMongoDb(MongodbTest test) {
        Query query = new Query(Criteria.where("id").is(test.getId()));
        Update update = new Update().set("age",test.getAge()).set("name",test.getName());
        mongoTemplate.updateFirst(query,update,MongodbTest.class);
    }

    /**
     * 删除对象
     * @param id
     */
    public void removeMongodb(String id) {
        Query query = new Query(Criteria.where("id").is(id));
        mongoTemplate.remove(query,MongodbTest.class);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
2.1.2 Service注入Dao
package com.example.service;

import com.example.dao.MongodbTestDao;
import com.example.entity.MongodbTest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * create by wbl
 * 2023/02/08
 */
@Service
public class MongodbTestService {
    @Autowired
    private MongodbTestDao mongodbTestDao;

    /**
     * 增加的方法
     */
    public void save(){
        MongodbTest mongodbTest = new MongodbTest();
        mongodbTest.setId(1);
        mongodbTest.setAge(19);
        mongodbTest.setName("招投标");
        mongodbTestDao.save(mongodbTest);
    }

    /**
     * 修改的方法
     */
    public void update() {
        MongodbTest mongodbTest = new MongodbTest();
        mongodbTest.setId(1);
        mongodbTest.setAge(20);
        mongodbTest.setName("国网商城");
        mongodbTestDao.updateMongoDb(mongodbTest);

    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
2.1.3 Controller层注入service
package com.example.controller;

import com.example.service.MongodbTestService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;


/**
 * create by wsh
 * 2019/10/30
 */
@RestController
public class MongodbTestController {
    @Autowired
    private MongodbTestService mongodbTestService;

    /**
     * 增加对象
     */
    @GetMapping("/save")
    public void save() {
        mongodbTestService.save();
    }

    @GetMapping("/update")
    public void update() {
        mongodbTestService.update();
    }

    @GetMapping("/delete")
    public void update2() {
        mongodbTestService.update();
    }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36

2.2 实现二:使用Example和Criteria封装查询条件

    /**
     *Query query = new Query();
     * query.addCriteria(Criteria.where("name").is(name));
     * @param key
     * @return
     */
    //把多个条件组合在一起
        public static Criteria where(String key) {
            return new Criteria(key);
        }

        //封装查询条件
        /**例如:
         *
         *创建匹配器,即如何使用查询条件
         * ExampleMatcher matcher = ExampleMatcher.matching() //构建对象
         *        .withStringMatcher(ExampleMatcher.StringMatcher.CONTAINING) //改变默认字符串匹配方式:模糊查询
         *        .withIgnoreCase(true) //改变默认大小写忽略方式:忽略大小写
         *        .withMatcher("name", ExampleMatcher.GenericPropertyMatchers.contains()) //标题采用“包含匹配”的方式查询
         *        .withIgnorePaths("pageNum", "pageSize");  //忽略属性,不参与查询
         *创建实例
         *Example<Student> example = Example.of(student, matcher);
         *Query query = new Query(Criteria.byExample(example));
         **/
        public static Criteria byExample(Object example) {
            return byExample(Example.of(example));
        }


        //封装查询条件
        public static Criteria byExample(Example<?> example) {
            return (new Criteria()).alike(example);
        }

        //匹配文档
        public static Criteria matchingDocumentStructure(MongoJsonSchema schema) {
            return (new Criteria()).andDocumentStructureMatches(schema);
        }

        //并且
        public Criteria and(String key) {
            return new Criteria(this.criteriaChain, key);
        }

        //是
        public Criteria is(@Nullable Object o) {
            if (!this.isValue.equals(NOT_SET)) {
                throw new InvalidMongoDbApiUsageException("Multiple 'is' values declared. You need to use 'and' with multiple criteria");
            } else if (this.lastOperatorWasNot()) {
                throw new InvalidMongoDbApiUsageException("Invalid query: 'not' can't be used with 'is' - use 'ne' instead.");
            } else {
                this.isValue = o;
                return this;
            }
        }

        //用于匹配正则表达式
        private boolean lastOperatorWasNot() {
            return !this.criteria.isEmpty() && "$not".equals(this.criteria.keySet().toArray()[this.criteria.size() - 1]);
        }

        //不等于
        public Criteria ne(@Nullable Object o) {
            this.criteria.put("$ne", o);
            return this;
        }

        //小于
        public Criteria lt(Object o) {
            this.criteria.put("$lt", o);
            return this;
        }

        //小于等于
        public Criteria lte(Object o) {
            this.criteria.put("$lte", o);
            return this;
        }

        //大于
        public Criteria gt(Object o) {
            this.criteria.put("$gt", o);
            return this;
        }

        //大于等于
        public Criteria gte(Object o) {
            this.criteria.put("$gte", o);
            return this;
        }

        //包含
        public Criteria in(Object... o) {
            if (o.length > 1 && o[1] instanceof Collection) {
                throw new InvalidMongoDbApiUsageException("You can only pass in one argument of type " + o[1].getClass().getName());
            } else {
                this.criteria.put("$in", Arrays.asList(o));
                return this;
            }
        }

        //包含
        public Criteria in(Collection<?> c) {
            this.criteria.put("$in", c);
            return this;
        }

        //与in相反
        public Criteria nin(Object... o) {
            return this.nin((Collection)Arrays.asList(o));
        }

        //与in相反
        public Criteria nin(Collection<?> o) {
            this.criteria.put("$nin", o);
            return this;
        }

        //取模(求余)运算 ,即:key对应的值%value==remainder(求余是否等于remainder)
        public Criteria mod(Number value, Number remainder) {
            List<Object> l = new ArrayList();
            l.add(value);
            l.add(remainder);
            this.criteria.put("$mod", l);
            return this;
        }

        //key键对应的集合包含col(all是包含关系,in是被包含关系)
        public Criteria all(Object... o) {
            return this.all((Collection)Arrays.asList(o));
        }

        public Criteria all(Collection<?> o) {
            this.criteria.put("$all", o);
            return this;
        }

        //匹配key所对应的集合的元素的指定数量(!!!不能进行像<5之类的范围匹配)
        public Criteria size(int s) {
            this.criteria.put("$size", s);
            return this;
        }

        //查询字段是否存在(true:存在,false:不存在)
        public Criteria exists(boolean b) {
            this.criteria.put("$exists", b);
            return this;
        }

        //基于 bson type来匹配一个元素的类型,像是按照类型ID来匹配
        public Criteria type(int t) {
            this.criteria.put("$type", t);
            return this;
        }

        public Criteria type(Type... types) {
            Assert.notNull(types, "Types must not be null!");
            Assert.noNullElements(types, "Types must not contain null.");
            this.criteria.put("$type", Arrays.asList(types).stream().map(Type::value).collect(Collectors.toList()));
            return this;
        }

        //取反
        public Criteria not() {
            return this.not((Object)null);
        }

        private Criteria not(@Nullable Object value) {
            this.criteria.put("$not", value);
            return this;
        }

        //模糊查询用
        public Criteria regex(String re) {
            return this.regex(re, (String)null);
        }

        public Criteria regex(String re, @Nullable String options) {
            return this.regex(this.toPattern(re, options));
        }

        public Criteria regex(Pattern pattern) {
            Assert.notNull(pattern, "Pattern must not be null!");
            if (this.lastOperatorWasNot()) {
                return this.not(pattern);
            } else {
                this.isValue = pattern;
                return this;
            }
        }

        public Criteria regex(BsonRegularExpression regex) {
            if (this.lastOperatorWasNot()) {
                return this.not(regex);
            } else {
                this.isValue = regex;
                return this;
            }
        }

        //
        private Pattern toPattern(String regex, @Nullable String options) {
            Assert.notNull(regex, "Regex string must not be null!");
            return Pattern.compile(regex, options == null ? 0 : BSON.regexFlags(options));
        }

        public Criteria withinSphere(Circle circle) {
            Assert.notNull(circle, "Circle must not be null!");
            this.criteria.put("$geoWithin", new GeoCommand(new Sphere(circle)));
            return this;
        }

        public Criteria within(Shape shape) {
            Assert.notNull(shape, "Shape must not be null!");
            this.criteria.put("$geoWithin", new GeoCommand(shape));
            return this;
        }

        //输出接近某一地理位置的有序文档
        public Criteria near(Point point) {
            Assert.notNull(point, "Point must not be null!");
            this.criteria.put("$near", point);
            return this;
        }

        //指定地理空间查询从最近到最远返回文档的点。 MongoDB 使用球面几何计算$nearSphere的距离
        public Criteria nearSphere(Point point) {
            Assert.notNull(point, "Point must not be null!");
            this.criteria.put("$nearSphere", point);
            return this;
        }

        //
        public Criteria intersects(GeoJson geoJson) {
            Assert.notNull(geoJson, "GeoJson must not be null!");
            this.criteria.put("$geoIntersects", geoJson);
            return this;
        }

        //创建一个地理空间标准,与nearSphere一起使用
        public Criteria maxDistance(double maxDistance) {
            if (!this.createNearCriteriaForCommand("$near", "$maxDistance", maxDistance) && !this.createNearCriteriaForCommand("$nearSphere", "$maxDistance", maxDistance)) {
                this.criteria.put("$maxDistance", maxDistance);
                return this;
            } else {
                return this;
            }
        }

        //mongodb地理空间计算逻辑
        public Criteria minDistance(double minDistance) {
            if (!this.createNearCriteriaForCommand("$near", "$minDistance", minDistance) && !this.createNearCriteriaForCommand("$nearSphere", "$minDistance", minDistance)) {
                this.criteria.put("$minDistance", minDistance);
                return this;
            } else {
                return this;
            }
        }

        //匹配查询
        public Criteria elemMatch(Criteria c) {
            this.criteria.put("$elemMatch", c.getCriteriaObject());
            return this;
        }

        //使用给定对象作为模式创建条件
        public Criteria alike(Example<?> sample) {
            this.criteria.put("$example", sample);
            this.criteriaChain.add(this);
            return this;
        }

        //创建一个criteria ($jsonSchema),根据MongoJsonSchema定义的给定结构匹配文档
        public Criteria andDocumentStructureMatches(MongoJsonSchema schema) {
            Assert.notNull(schema, "Schema must not be null!");
            Criteria schemaCriteria = new Criteria();
            schemaCriteria.criteria.putAll(schema.toDocument());
            return this.registerCriteriaChainElement(schemaCriteria);
        }

        public Criteria.BitwiseCriteriaOperators bits() {
            return new Criteria.BitwiseCriteriaOperatorsImpl(this);
        }

        //或者

        /**
         * Aggregation agg = Aggregation.newAggregation(
         *     Aggregation.match(new Criteria()
         *             .andOperator(Criteria.where("onlineTime").gt(new Date()))
         *             .orOperator( Criteria.where("offlineTime").gt(new Date())
         *     ,Criteria.where("offlineTime").exists(false) ))
         * @param criteria
         * @return
         */
        public Criteria orOperator(Criteria... criteria) {
            BasicDBList bsonList = this.createCriteriaList(criteria);
            return this.registerCriteriaChainElement((new Criteria("$or")).is(bsonList));
        }

        //非或者
        public Criteria norOperator(Criteria... criteria) {
            BasicDBList bsonList = this.createCriteriaList(criteria);
            return this.registerCriteriaChainElement((new Criteria("$nor")).is(bsonList));
        }

        //并且
        public Criteria andOperator(Criteria... criteria) {
            BasicDBList bsonList = this.createCriteriaList(criteria);
            return this.registerCriteriaChainElement((new Criteria("$and")).is(bsonList));
        }

        private Criteria registerCriteriaChainElement(Criteria criteria) {
            if (this.lastOperatorWasNot()) {
                throw new IllegalArgumentException("operator $not is not allowed around criteria chain element: " + criteria.getCriteriaObject());
            } else {
                this.criteriaChain.add(criteria);
                return this;
            }
        }

        @Nullable
        public String getKey() {
            return this.key;
        }

        public Document getCriteriaObject() {
            if (this.criteriaChain.size() == 1) {
                return ((Criteria)this.criteriaChain.get(0)).getSingleCriteriaObject();
            } else if (CollectionUtils.isEmpty(this.criteriaChain) && !CollectionUtils.isEmpty(this.criteria)) {
                return this.getSingleCriteriaObject();
            } else {
                Document criteriaObject = new Document();
                Iterator var2 = this.criteriaChain.iterator();

                while(var2.hasNext()) {
                    Criteria c = (Criteria)var2.next();
                    Document document = c.getSingleCriteriaObject();
                    Iterator var5 = document.keySet().iterator();

                    while(var5.hasNext()) {
                        String k = (String)var5.next();
                        this.setValue(criteriaObject, k, document.get(k));
                    }
                }

                return criteriaObject;
            }
        }

        protected Document getSingleCriteriaObject() {
            Document document = new Document();
            boolean not = false;
            Iterator var3 = this.criteria.entrySet().iterator();

            while(true) {
                while(var3.hasNext()) {
                    Entry<String, Object> entry = (Entry)var3.next();
                    String key = (String)entry.getKey();
                    Object value = entry.getValue();
                    if (requiresGeoJsonFormat(value)) {
                        value = new Document("$geometry", value);
                    }

                    if (not) {
                        Document notDocument = new Document();
                        notDocument.put(key, value);
                        document.put("$not", notDocument);
                        not = false;
                    } else if ("$not".equals(key) && value == null) {
                        not = true;
                    } else {
                        document.put(key, value);
                    }
                }

                if (!StringUtils.hasText(this.key)) {
                    if (not) {
                        return new Document("$not", document);
                    }

                    return document;
                }

                Document queryCriteria = new Document();
                if (!NOT_SET.equals(this.isValue)) {
                    queryCriteria.put(this.key, this.isValue);
                    queryCriteria.putAll(document);
                } else {
                    queryCriteria.put(this.key, document);
                }

                return queryCriteria;
            }
        }

        private BasicDBList createCriteriaList(Criteria[] criteria) {
            BasicDBList bsonList = new BasicDBList();
            Criteria[] var3 = criteria;
            int var4 = criteria.length;

            for(int var5 = 0; var5 < var4; ++var5) {
                Criteria c = var3[var5];
                bsonList.add(c.getCriteriaObject());
            }

            return bsonList;
        }

        private void setValue(Document document, String key, Object value) {
            Object existing = document.get(key);
            if (existing == null) {
                document.put(key, value);
            } else {
                throw new InvalidMongoDbApiUsageException("Due to limitations of the com.mongodb.BasicDocument, you can't add a second '" + key + "' expression specified as '" + key + " : " + value + "'. Criteria already contains '" + key + " : " + existing + "'.");
            }
        }

        private boolean createNearCriteriaForCommand(String command, String operation, double maxDistance) {
            if (!this.criteria.containsKey(command)) {
                return false;
            } else {
                Object existingNearOperationValue = this.criteria.get(command);
                if (existingNearOperationValue instanceof Document) {
                    ((Document)existingNearOperationValue).put(operation, maxDistance);
                    return true;
                } else if (existingNearOperationValue instanceof GeoJson) {
                    Document dbo = (new Document("$geometry", existingNearOperationValue)).append(operation, maxDistance);
                    this.criteria.put(command, dbo);
                    return true;
                } else {
                    return false;
                }
            }
        }

        public boolean equals(Object obj) {
            if (this == obj) {
                return true;
            } else if (obj != null && this.getClass().equals(obj.getClass())) {
                Criteria that = (Criteria)obj;
                if (this.criteriaChain.size() != that.criteriaChain.size()) {
                    return false;
                } else {
                    for(int i = 0; i < this.criteriaChain.size(); ++i) {
                        Criteria left = (Criteria)this.criteriaChain.get(i);
                        Criteria right = (Criteria)that.criteriaChain.get(i);
                        if (!this.simpleCriteriaEquals(left, right)) {
                            return false;
                        }
                    }

                    return true;
                }
            } else {
                return false;
            }
        }

        private boolean simpleCriteriaEquals(Criteria left, Criteria right) {
            boolean keyEqual = left.key == null ? right.key == null : left.key.equals(right.key);
            boolean criteriaEqual = left.criteria.equals(right.criteria);
            boolean valueEqual = this.isEqual(left.isValue, right.isValue);
            return keyEqual && criteriaEqual && valueEqual;
        }

        //判断是否相等
        private boolean isEqual(Object left, Object right) {
            if (left == null) {
                return right == null;
            } else if (Pattern.class.isInstance(left)) {
                if (!Pattern.class.isInstance(right)) {
                    return false;
                } else {
                    Pattern leftPattern = (Pattern)left;
                    Pattern rightPattern = (Pattern)right;
                    return leftPattern.pattern().equals(rightPattern.pattern()) && leftPattern.flags() == rightPattern.flags();
                }
            } else {
                return ObjectUtils.nullSafeEquals(left, right);
            }
        }

        public int hashCode() {
            int result = 17;
            int result = result + ObjectUtils.nullSafeHashCode(this.key);
            result += this.criteria.hashCode();
            result += ObjectUtils.nullSafeHashCode(this.isValue);
            return result;
        }

        private static boolean requiresGeoJsonFormat(Object value) {
            return value instanceof GeoJson || value instanceof GeoCommand && ((GeoCommand)value).getShape() instanceof GeoJson;
        }

        private static class BitwiseCriteriaOperatorsImpl implements Criteria.BitwiseCriteriaOperators {
            private final Criteria target;

            BitwiseCriteriaOperatorsImpl(Criteria target) {
                this.target = target;
            }

            public Criteria allClear(int numericBitmask) {
                return this.numericBitmask("$bitsAllClear", numericBitmask);
            }

            public Criteria allClear(String bitmask) {
                return this.stringBitmask("$bitsAllClear", bitmask);
            }

            public Criteria allClear(List<Integer> positions) {
                return this.positions("$bitsAllClear", positions);
            }

            public Criteria allSet(int numericBitmask) {
                return this.numericBitmask("$bitsAllSet", numericBitmask);
            }

            public Criteria allSet(String bitmask) {
                return this.stringBitmask("$bitsAllSet", bitmask);
            }

            public Criteria allSet(List<Integer> positions) {
                return this.positions("$bitsAllSet", positions);
            }

            public Criteria anyClear(int numericBitmask) {
                return this.numericBitmask("$bitsAnyClear", numericBitmask);
            }

            public Criteria anyClear(String bitmask) {
                return this.stringBitmask("$bitsAnyClear", bitmask);
            }

            public Criteria anyClear(List<Integer> positions) {
                return this.positions("$bitsAnyClear", positions);
            }

            public Criteria anySet(int numericBitmask) {
                return this.numericBitmask("$bitsAnySet", numericBitmask);
            }

            public Criteria anySet(String bitmask) {
                return this.stringBitmask("$bitsAnySet", bitmask);
            }

            public Criteria anySet(List<Integer> positions) {
                return this.positions("$bitsAnySet", positions);
            }

            private Criteria positions(String operator, List<Integer> positions) {
                Assert.notNull(positions, "Positions must not be null!");
                Assert.noNullElements(positions.toArray(), "Positions must not contain null values.");
                this.target.criteria.put(operator, positions);
                return this.target;
            }

            private Criteria stringBitmask(String operator, String bitmask) {
                Assert.hasText(bitmask, "Bitmask must not be null!");
                this.target.criteria.put(operator, new Binary(Base64Utils.decodeFromString(bitmask)));
                return this.target;
            }

            private Criteria numericBitmask(String operator, int bitmask) {
                this.target.criteria.put(operator, bitmask);
                return this.target;
            }
        }

        public interface BitwiseCriteriaOperators {
            Criteria allClear(int var1);

            Criteria allClear(String var1);

            Criteria allClear(List<Integer> var1);

            Criteria allSet(int var1);

            Criteria allSet(String var1);

            Criteria allSet(List<Integer> var1);

            Criteria anyClear(int var1);

            Criteria anyClear(String var1);

            Criteria anyClear(List<Integer> var1);

            Criteria anySet(int var1);

            Criteria anySet(String var1);

            Criteria anySet(List<Integer> var1);
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243
  • 244
  • 245
  • 246
  • 247
  • 248
  • 249
  • 250
  • 251
  • 252
  • 253
  • 254
  • 255
  • 256
  • 257
  • 258
  • 259
  • 260
  • 261
  • 262
  • 263
  • 264
  • 265
  • 266
  • 267
  • 268
  • 269
  • 270
  • 271
  • 272
  • 273
  • 274
  • 275
  • 276
  • 277
  • 278
  • 279
  • 280
  • 281
  • 282
  • 283
  • 284
  • 285
  • 286
  • 287
  • 288
  • 289
  • 290
  • 291
  • 292
  • 293
  • 294
  • 295
  • 296
  • 297
  • 298
  • 299
  • 300
  • 301
  • 302
  • 303
  • 304
  • 305
  • 306
  • 307
  • 308
  • 309
  • 310
  • 311
  • 312
  • 313
  • 314
  • 315
  • 316
  • 317
  • 318
  • 319
  • 320
  • 321
  • 322
  • 323
  • 324
  • 325
  • 326
  • 327
  • 328
  • 329
  • 330
  • 331
  • 332
  • 333
  • 334
  • 335
  • 336
  • 337
  • 338
  • 339
  • 340
  • 341
  • 342
  • 343
  • 344
  • 345
  • 346
  • 347
  • 348
  • 349
  • 350
  • 351
  • 352
  • 353
  • 354
  • 355
  • 356
  • 357
  • 358
  • 359
  • 360
  • 361
  • 362
  • 363
  • 364
  • 365
  • 366
  • 367
  • 368
  • 369
  • 370
  • 371
  • 372
  • 373
  • 374
  • 375
  • 376
  • 377
  • 378
  • 379
  • 380
  • 381
  • 382
  • 383
  • 384
  • 385
  • 386
  • 387
  • 388
  • 389
  • 390
  • 391
  • 392
  • 393
  • 394
  • 395
  • 396
  • 397
  • 398
  • 399
  • 400
  • 401
  • 402
  • 403
  • 404
  • 405
  • 406
  • 407
  • 408
  • 409
  • 410
  • 411
  • 412
  • 413
  • 414
  • 415
  • 416
  • 417
  • 418
  • 419
  • 420
  • 421
  • 422
  • 423
  • 424
  • 425
  • 426
  • 427
  • 428
  • 429
  • 430
  • 431
  • 432
  • 433
  • 434
  • 435
  • 436
  • 437
  • 438
  • 439
  • 440
  • 441
  • 442
  • 443
  • 444
  • 445
  • 446
  • 447
  • 448
  • 449
  • 450
  • 451
  • 452
  • 453
  • 454
  • 455
  • 456
  • 457
  • 458
  • 459
  • 460
  • 461
  • 462
  • 463
  • 464
  • 465
  • 466
  • 467
  • 468
  • 469
  • 470
  • 471
  • 472
  • 473
  • 474
  • 475
  • 476
  • 477
  • 478
  • 479
  • 480
  • 481
  • 482
  • 483
  • 484
  • 485
  • 486
  • 487
  • 488
  • 489
  • 490
  • 491
  • 492
  • 493
  • 494
  • 495
  • 496
  • 497
  • 498
  • 499
  • 500
  • 501
  • 502
  • 503
  • 504
  • 505
  • 506
  • 507
  • 508
  • 509
  • 510
  • 511
  • 512
  • 513
  • 514
  • 515
  • 516
  • 517
  • 518
  • 519
  • 520
  • 521
  • 522
  • 523
  • 524
  • 525
  • 526
  • 527
  • 528
  • 529
  • 530
  • 531
  • 532
  • 533
  • 534
  • 535
  • 536
  • 537
  • 538
  • 539
  • 540
  • 541
  • 542
  • 543
  • 544
  • 545
  • 546
  • 547
  • 548
  • 549
  • 550
  • 551
  • 552
  • 553
  • 554
  • 555
  • 556
  • 557
  • 558
  • 559
  • 560
  • 561
  • 562
  • 563
  • 564
  • 565
  • 566
  • 567
  • 568
  • 569
  • 570
  • 571
  • 572
  • 573
  • 574
  • 575
  • 576
  • 577
  • 578
  • 579
  • 580
  • 581
  • 582
  • 583
  • 584
  • 585
  • 586
  • 587
  • 588
  • 589
  • 590
  • 591
  • 592
  • 593
  • 594
  • 595
  • 596

3、MongoTemplate结合BasicQueryBasicQuery是Query的子类

4、MongoTemplate结合Aggregation使用Aggregation聚合查询

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/261049?site
推荐阅读
相关标签
  

闽ICP备14008679号