Spring Data MongoDB 教程

Criteria 其他查询

前面我们介绍了 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;
}
说说我的看法
全部评论(
没有评论
关于
本网站专注于 Java、数据库(MySQL、Oracle)、Linux、软件架构及大数据等多领域技术知识分享。涵盖丰富的原创与精选技术文章,助力技术传播与交流。无论是技术新手渴望入门,还是资深开发者寻求进阶,这里都能为您提供深度见解与实用经验,让复杂编码变得轻松易懂,携手共赴技术提升新高度。如有侵权,请来信告知:hxstrive@outlook.com
公众号