前面我们介绍了 Criteria 关于比较、逻辑、元素、地理空间、数组等查询方法的具体用法,下面将介绍 Creteria 中其他的一些方法,这些方法定义如下:
Criteria alike(Example<?> sample) 使用给定的对象作为模式创建一个 Criteria
Criteria and(String key) 静态工厂方法,使用所提供的 key 创建一个 Criteria
static Criteria byExample(Object example) 静态工厂方法,创建一个与 example 对象相匹配的 Criteria
static Criteria byExample(Example<?> example) 静态工厂方法,创建一个与 example 对象相匹配的 Criteria
static Criteria where(String key) 静态工厂方法,使用所提供的 key 创建一个Criteria
static Criteria matchingDocumentStructure(MongoJsonSchema schema) 静态工厂方法,使用 ($jsonSchema) 操作符创建一个与 MongoJsonSchema 定义的给定结构相匹配的文件的 Criteria
String getKey() 获取标识 key
org.bson.Document getCriteriaObject() 获取对象的 Document 表示形式
Criteria sampleRate(double sampleRate) 使用 $sampleRate 操作符创建一个 Criteria
该示例直接演示上面这些方法如何使用,代码如下:
package com.hxstrive.springdata.mongodb; import com.hxstrive.springdata.mongodb.entity.Person; import com.mongodb.client.model.IndexOptions; import org.bson.Document; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.data.domain.Example; import org.springframework.data.domain.ExampleMatcher; 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.schema.MongoJsonSchema; import java.util.List; import static org.springframework.data.mongodb.core.schema.JsonSchemaProperty.number; import static org.springframework.data.mongodb.core.schema.JsonSchemaProperty.string; /** * 其他查询 * @author hxstrive.com */ @SpringBootTest class CriteriaDemo8 { @Autowired private MongoTemplate mongoTemplate; @BeforeEach public void init() { // 删除集合 mongoTemplate.dropCollection(Person.class); // 准备数据 // 对应年龄的二进制字符串如下: // 27 ==> 00011011 // 30 ==> 00011110 // 47 ==> 00101111 // 20 ==> 00010100 mongoTemplate.insert(Person.builder().id(100).name("Tom").age(27).email("Tom@sina.com") .interests(new String[]{ "basketball" }) .coordinates(new Double[]{ 116.424966, 39.936625 }) .build()); mongoTemplate.insert(Person.builder().id(200).name("Helen").age(30).email("Helen@outlook.com") .interests(new String[]{ "basketball", "badminton" }) .coordinates(new Double[]{ 114.530044, 38.056057 }) .build()); mongoTemplate.insert(Person.builder().id(300).name("Bill").age(47).email("bill@gmail.com") .interests(new String[]{ "football", "badminton" }) .coordinates(new Double[]{ 114.530044, 38.056057 }) .summary("I am a software engineer and I like Java.") .build()); mongoTemplate.insert(Person.builder().id(400).name("Joe").age(20).email("joe@163.com") .interests(new String[]{ "badminton" }) .coordinates(new Double[]{ 114.364468, 30.650303 }) .summary("I'm a pianist.").build()); // 创建索引 String collectionName = mongoTemplate.getCollectionName(Person.class); mongoTemplate.getCollection(collectionName).createIndex( // 为 coordinates 字段创建 2d 类型的索引 new Document("coordinates", "2d"), // 设置索引名为 idx_coordinates,background 指定索引是否应该在后台创建 new IndexOptions().background(false).name("idx_coordinates")); } @Test public void and() { // 查询 age 大于 30,且 name 等于 Bill 的文档 // { "age" : { "$gt" : 30}, "name" : "Bill"} Criteria criteria = Criteria.where("age").gt(30).and("name").is("Bill"); List<Person> personList = mongoTemplate.query(Person.class) .matching(Query.query(criteria)).all(); for(Person person : personList) { System.out.println(person); } // 结果: // Person(id=300, name=Bill, age=47, email=bill@gmail.com, summary=I am a software engineer and I like Java., coordinates=[114.530044, 38.056057], interests=[football, badminton]) } @Test public void alike() { // 使用 Person 的一个实例构建条件 // 查询 name 等于 Bill,或 age 等于 27,或 id 等于 200 的文档 // 其中: // ExampleMatcher.matchingAny() 表示任意一个字段匹配就算匹配成功 // ExampleMatcher.matchingAll() 表示所有条件都必须匹配 Example<Person> example = Example.of( Person.builder().name("Bill").age(27).id(200).build(), ExampleMatcher.matchingAny()); Criteria criteria = new Criteria().alike(example); // { "$or" : [{ "_id" : 200}, { "name" : "Bill"}, { "age" : 27}], "_class" : { "$in" : ["com.hxstrive.springdata.mongodb.entity.Person"]}} List<Person> personList = mongoTemplate.query(Person.class) .matching(Query.query(criteria)).all(); for(Person person : personList) { System.out.println(person); } // 结果: // Person(id=100, name=Tom, age=27, email=Tom@sina.com, summary=null, coordinates=[116.424966, 39.936625], interests=[basketball]) // Person(id=200, name=Helen, age=30, email=Helen@outlook.com, summary=null, coordinates=[114.530044, 38.056057], interests=[basketball, badminton]) // Person(id=300, name=Bill, age=47, email=bill@gmail.com, summary=I am a software engineer and I like Java., coordinates=[114.530044, 38.056057], interests=[football, badminton]) } @Test public void byExample() { // 查询 name 等于 Bill,或 age 等于 27,或 id 等于 200 的文档 Example<Person> example = Example.of( Person.builder().name("Bill").age(27).id(200).build(), ExampleMatcher.matchingAny()); Criteria criteria = Criteria.byExample(example); // { "$or" : [{ "_id" : 200}, { "name" : "Bill"}, { "age" : 27}], "_class" : { "$in" : ["com.hxstrive.springdata.mongodb.entity.Person"]}} List<Person> personList = mongoTemplate.query(Person.class) .matching(Query.query(criteria)).all(); for(Person person : personList) { System.out.println(person); } // 结果: // Person(id=100, name=Tom, age=27, email=Tom@sina.com, summary=null, coordinates=[116.424966, 39.936625], interests=[basketball]) // Person(id=200, name=Helen, age=30, email=Helen@outlook.com, summary=null, coordinates=[114.530044, 38.056057], interests=[basketball, badminton]) // Person(id=300, name=Bill, age=47, email=bill@gmail.com, summary=I am a software engineer and I like Java., coordinates=[114.530044, 38.056057], interests=[football, badminton]) } @Test public void getKey() { Criteria criteria = Criteria.where("name").is("Bill"); System.out.println(criteria.getKey()); // 结果: // name } @Test public void getCriteriaObject() { Criteria criteria = Criteria.where("name").is("Bill").and("age").lt(40); Document document = criteria.getCriteriaObject(); System.out.println(document.toJson()); // 结果: // {"name": "Bill", "age": {"$lt": 40}} } @Test public void matchingDocumentStructure() { MongoJsonSchema schema = MongoJsonSchema.builder() .required("name", "age") .properties( string("name").possibleValues("Helen", "Bill", "Joe"), number("age").gt(20).lt(120) ).build(); System.out.println(schema.schemaDocument().toJson()); // 输出: // {"type": "object", "required": ["name", "age"], "properties": {"name": {"type": "string", "enum": ["Helen", "Bill", "Joe"]}, "age": {"type": "number", "minimum": 20, "exclusiveMinimum": true, "maximum": 120, "exclusiveMaximum": true}}} Criteria criteria = Criteria.matchingDocumentStructure(schema).and("age").gt(25); List<Person> personList = mongoTemplate.query(Person.class) .matching(Query.query(criteria)).all(); for(Person person : personList) { System.out.println(person); } // 结果: // Person(id=200, name=Helen, age=30, email=Helen@outlook.com, summary=null, coordinates=[114.530044, 38.056057], interests=[basketball, badminton]) // Person(id=300, name=Bill, age=47, email=bill@gmail.com, summary=I am a software engineer and I like Java., coordinates=[114.530044, 38.056057], interests=[football, badminton]) } }
其中,Person 实体代码如下:
package com.hxstrive.springdata.mongodb.entity; import lombok.Builder; import lombok.Data; import lombok.ToString; @Data @ToString @Builder public class Person { /** 用户ID */ private int id; /** 用户姓名 */ private String name; /** 年龄 */ private int age; /** 电子邮件 */ private String email; /** 个人说明 */ private String summary; /** 经纬度信息 */ private Double[] coordinates; /** 个人兴趣 */ private String[] interests; }