Spring Data MongoDB 教程

Criteria 按位查询

在 MongoDB 中,提供了几个按位的操作符,它们分别为 $bitsAllClear、$bitsAllSet、$bitsAnyClear 和 $bitsAnySet 操作符,这些操作符详细描述如下:

  • $bitsAllClear 操作符用来匹配数字或二进制值,查询给出的所有位置对应位的二进制值为 0 的文档。例如:

// 查询字段 age 是否在位置 1 和位置 5 有位清除
db.t_01.find({
    "age": {
        $bitsAllClear:[1,5]
    }
})
  • $bitsAllSet 操作符用来匹配数字或二进制值,查询给出的所有位置对应位的二进制值为 1 的文档。例如:

// 查询字段 age 是否具有在位置 1 和位置 5 设置的位 1
db.t_01.find({
    "age": {
        $bitsAllSet:[1,5]
    } 
})
  • $bitsAnyClear 操作符用来匹配数字或二进制值,查询给出的一组位置中任意一个位置对应位的二进制值为 0 的文档。例如:

// 查询字段 age 在位置 1 或位置 5 具有位清除的文档
db.t_01.find({
    "age": {
        $bitsAnyClear:[1,5]
    } 
})
  • $bitsAnySet 操作符用来匹配数字或二进制值,查询给出的一组位置中任意一个位置对应位的二进制值为 1 的文档。例如:

// 查询字段 age 在位置 1 或位置 5 为 1 的文档
db.t_01.find({
    "age": {
        $bitsAnySet:[1,5]
    } 
})

下面将介绍怎样使用 Criteria 实现按位查询,Criteria.BitwiseCriteriaOperators 接口定义的按位查询方法如下:

  • Criteria allClear(int numericBitmask) 使用 $bitsAllClear 创建一个 Criteria,以匹配所有给定的比特位置为空(即0)的文档。

  • Criteria allClear(String bitmask) 使用 $bitsAllClear 创建一个 Criteria,以匹配所有给定的比特位置为空(即0)的文档。

  • Criteria allClear(List<Integer> positions) 使用 $bitsAllClear 创建一个 Criteria,以匹配所有给定的比特位置为空(即0)的文档。

  • Criteria anyClear(int numericBitmask) 使用 $bitsAllClear 创建一个 Criteria,以匹配任何给定的比特位置为空(即0)的文档。

  • Criteria anyClear(String bitmask) 使用 $bitsAllClear 创建一个 Criteria,以匹配任何给定的比特位置为空(即0)的文档。

  • Criteria anyClear(List<Integer> positions) 使用 $bitsAllClear 创建一个 Criteria,以匹配任何给定的比特位置为空(即0)的文档。

  • Criteria allSet(int numericBitmask) 使用 $bitsAllSet 创建一个 Criteria,匹配所有给定的比特位置被设置(即1)的文档。

  • Criteria allSet(String bitmask) 使用 $bitsAllSet 创建一个 Criteria,匹配所有给定的比特位置被设置(即1)的文档。

  • Criteria allSet(List<Integer> positions) 使用 $bitsAllSet 创建一个 Criteria,匹配所有给定的比特位置被设置(即1)的文档。

  • Criteria anySet(int numericBitmask) 使用 $bitsAllSet 创建一个 Criteria,以匹配任何给定的比特位置被设置(即1)的文档。

  • Criteria anySet(String bitmask) 使用 $bitsAnySet 创建一个 Criteria,以匹配任何给定的比特位置被设置(即1)的文档。

  • Criteria anySet(List<Integer> positions) 使用 $bitsAnySet 创建一个 Criteria,以匹配任何给定的比特位置被设置(即1)的文档。

示例

下面示例将演示怎样使用 Criteria.BitwiseCriteriaOperators 接口的按位查询方法实现按位查询操作,示例如下:

package com.hxstrive.springdata.mongodb;

import com.hxstrive.springdata.mongodb.entity.Person;
import com.mongodb.client.model.IndexOptions;
import org.bson.Document;
import org.bson.types.Binary;
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.util.Base64Utils;

import java.util.Arrays;
import java.util.Base64;
import java.util.List;

/**
* 按位查询
* @author hxstrive.com
*/
@SpringBootTest
class CriteriaDemo7 {

   @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 allClear() {
       // 查询 age 中指定的所有位的值为 0 的文档
       // 27 ==> 00011011
       // 30 ==> 00011110
       // 47 ==> 00101111
       // 20 ==> 00010100   匹配
       Criteria criteria = Criteria.where("age").bits()
               .allClear(Arrays.asList(0,1,3));

       List<Person> personList = mongoTemplate.query(Person.class)
               .matching(Query.query(criteria)).all();
       for(Person person : personList) {
           System.out.println(person);
       }
       // 结果:
       // Person(id=400, name=Joe, age=20, email=joe@163.com, summary=I'm a pianist., coordinates=[114.364468, 30.650303], interests=[badminton])
       // 根据查询结果可知,成功匹配了 age=20 的文档
       // 27、30、47 和 20 几个年龄,只有 20 符合条件,注意:位的位置从右向左数,第一位位置为0
       // 20 ==> 00010100
       //        76543210  位置
   }

   @Test
   public void allClear2() {
       // 查询 age 中指定的所有位的值为 0 的文档
       // 27 ==> 00011011
       // 30 ==> 00011110
       // 47 ==> 00101111
       // 20 ==> 00010100   匹配
       // 将我们需要指定的位的位值设置位 1,我们将第 0、1、3 为设置位1,如下:
       // 掩码:00001011 ==> 0x0B
       Criteria criteria = Criteria.where("age").bits().allClear(0x0B);

       List<Person> personList = mongoTemplate.query(Person.class)
               .matching(Query.query(criteria)).all();
       for(Person person : personList) {
           System.out.println(person);
       }
       // 结果:
       // Person(id=400, name=Joe, age=20, email=joe@163.com, summary=I'm a pianist., coordinates=[114.364468, 30.650303], interests=[badminton])
   }

   @Test
   public void anyClear() {
       // 查询 age 中指定的任意位的值为 0 的文档
       // 27 ==> 00011011
       // 30 ==> 00011110   匹配
       // 47 ==> 00101111
       // 20 ==> 00010100   匹配
       Criteria criteria = Criteria.where("age").bits()
               .anyClear(Arrays.asList(0,1,3));

       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=400, name=Joe, age=20, email=joe@163.com, summary=I'm a pianist., coordinates=[114.364468, 30.650303], interests=[badminton])
   }

   @Test
   public void allSet() {
       // 查询 age 中指定的所有位的值为 1 的文档
       // 27 ==> 00011011
       // 30 ==> 00011110
       // 47 ==> 00101111   匹配
       // 20 ==> 00010100
       Criteria criteria = Criteria.where("age").bits()
               .allSet(Arrays.asList(0,5));

       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 anySet() {
       // 查询 age 中指定的所有位的值为 1 的文档
       // 27 ==> 00011011   匹配
       // 30 ==> 00011110
       // 47 ==> 00101111   匹配
       // 20 ==> 00010100
       Criteria criteria = Criteria.where("age").bits()
               .anySet(Arrays.asList(0,5));

       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=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
公众号