Spring Data MongoDB 教程

Criteria 诊断查询

MongoDB 提供了多个诊断操作符,常用诊断操作符如下:

  • $expr 操作符允许在查询语句中使用聚合表达式,$expr 可以构建查询表达式,在匹配时,比较同一文档中的字段。例如:

-- 两个字段比较,返回 "sal" 比 "age" 大的文档:
db.t_01.find({ $expr: { $gt: ["age","sal"] } })
  • $jsonSchema 操作符可以被用于文档验证器,用于集合模式验证。例如:

-- 定义一个 users 集合模式验证:
db.createCollection("users",  {
   validator: {
       $jsonSchema: {
           bsonType: "object",
           required: ["name", "sex"],
           properties: {
               name: {
                   bsonType: "string",
                   description: "must be a  string and is required"
               },
               age: {
                   bsonType: "int",
                   description: "must be a integer and is not  required"
               },
               sex: {
                   enum: ["male" , "female"],
                   description: "can only be one of the enum  values and is required"
               }
           }
       }
   }
)

-- 往集合 users 插入数据
db.users.insert({ "name":"gg", "sex":"male" })
  • $mod 操作符用来对字段的值执行除以指定值取余数运算。例如:

-- 返回 "age" 字段值被 3 整除的文档
db.t_01.find({ "age" : { $mod : [3,0] } })
  • $regex 操作符用来选择与指定正则表达式匹配的文档,MongoDB 使用 Perl 兼容正则表达式版本 8.41。例如:

-- 查询 "name" 结尾是 tor 三个字符的文档
db.t_01.find({"name":  {$regex : /tor$/ } })
  • $text 操作符用来对具有文本索引的字段执行文本搜索。例如:

-- 在 t_01 集合的 "name" 上创建 text 索引
db.t_01.createIndex({ "name" : "text"})

-- 使用全文搜索
db.t_01.find({$text: { $search: "david" } } )
  • $where 操作符用来匹配满足 JavaScript 表达式的文档,使用 $where 操作符将包含 JavaScript 表达式的字符串或完整的 JavaScript 函数传递给查询系统。例如:

-- 查询 "name" 字段为 david 的文档
db.t_01.find({ $where : function() {
       return (this.name == "david")
   }
})

下面将介绍怎样使用 Criteria 实现诊断查询,Criteria 类定义的诊断查询方法如下:

  • Criteria andDocumentStructureMatches(MongoJsonSchema schema) 创建一个 Criteria($jsonSchema),根据 MongoJsonSchema 定义的给定结构匹配文档。

  • Criteria mod(Number value, Number remainder) 使用 $mod 操作符创建一个 Criteria

  • Criteria regex(String regex) 使用 $regex 操作符创建一个 Criteria

  • Criteria regex(String regex, String options) 使用 $regex 操作符创建一个 Criteria

示例

下面示例将演示怎样使用 Criteria 的诊断查询方法实现诊断查询,示例如下:

package com.hxstrive.springdata.mongodb;

import com.hxstrive.springdata.mongodb.entity.Person;
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.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.JsonSchemaObject;
import org.springframework.data.mongodb.core.schema.MongoJsonSchema;

import java.util.List;

import static org.springframework.data.mongodb.core.schema.JsonSchemaProperty.*;

/**
*
* @author hxstrive.com
*/
@SpringBootTest
class CriteriaDemo4 {

   @Autowired
   private MongoTemplate mongoTemplate;

   @BeforeEach
   public void init() {
       // 删除集合
       mongoTemplate.dropCollection(Person.class);

       // 准备数据
       mongoTemplate.insert(Person.builder().id(100).name("Tom").age(27).email("Tom@sina.com").build());
       mongoTemplate.insert(Person.builder().id(200).name("Helen").age(30).email("Helen@outlook.com").build());
       mongoTemplate.insert(Person.builder().id(300).name("Bill").age(47).email("bill@gmail.com").build());
       mongoTemplate.insert(Person.builder().id(400).name("Joe").age(20).email("joe@163.com")
               .summary("User description information").build());
   }

   @Test
   public void mod() {
       // 查询文档中 age 字段的值能够被 10 整除
       Criteria criteria = Criteria.where("age").mod(10, 0);

       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)
       // Person(id=400, name=Joe, age=20, email=joe@163.com, summary=User description information)
   }


   @Test
   public void regex() {
       // 查询文档中 name 字段的值由三个大小写字母组成的文档
       Criteria criteria = Criteria.where("name").regex("^[a-zA-Z]{3}$");

       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)
       // Person(id=400, name=Joe, age=20, email=joe@163.com, summary=User description information)
   }


   @Test
   public void andDocumentStructureMatches() {
       /**
        * {
        *     "type":"object",
        *     "required":["name", "age"],
        *     "properties":{
        *         "name":{
        *             "type":"string",
        *             "enum":["Tom","Helen","Bill","Joe"]
        *         },
        *         "age":{
        *             "type":"number",
        *             "minimum":20,
        *             "exclusiveMinimum":true,
        *             "maximum":120,
        *             "exclusiveMaximum":true
        *         }
        *     }
        * }
        */
       MongoJsonSchema schema = MongoJsonSchema.builder()
               .required("name", "age")
               .properties(
                       string("name").possibleValues("Tom", "Helen", "Bill", "Joe"),
                       number("age").gt(20).lt(120)
               ).build();

       System.out.println(schema.schemaDocument().toJson());

       Criteria criteria = Criteria.where("age").gt(20)
               .andDocumentStructureMatches(schema);

       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)
       // Person(id=200, name=Helen, age=30, email=Helen@outlook.com, summary=null)
       // Person(id=300, name=Bill, age=47, email=bill@gmail.com, summary=null)
   }


   @Test
   public void andDocumentStructureMatches2() {
       /**
        * {
        *     "type":"object",
        *     "required":["name", "age"],
        *     "properties":{
        *         "name":{
        *             "type":"string",
        *             "enum":["Tom","Joe"]
        *         },
        *         "age":{
        *             "type":"number",
        *             "minimum":40,
        *             "exclusiveMinimum":true,
        *             "maximum":120,
        *             "exclusiveMaximum":true
        *         }
        *     }
        * }
        */
       MongoJsonSchema schema = MongoJsonSchema.builder()
               .required("name", "age")
               .properties(
                       string("name").possibleValues("Tom", "Joe"),
                       number("age").gt(40).lt(120)
               ).build();

       System.out.println(schema.schemaDocument().toJson());

       Criteria criteria = Criteria.where("age").gt(20)
               .andDocumentStructureMatches(schema);

       List<Person> personList = mongoTemplate.query(Person.class)
               .matching(Query.query(criteria)).all();
       for(Person person : personList) {
           System.out.println(person);
       }
       // 结果:
       // 没有匹配到任何文档
   }

}

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