springboot项目 - Mongo项目实战-查询相关

一.用mongoTemplate 与 Criteria一同使用

MongoTemplate是Spring Data MongoDB中的一个核心类,它提供了一种方式来操作MongoDB数据库。这种操作方式不仅简单易用,而且非常灵活。我们可以通过MongoTemplate来完成大部分的工作,包括创建、更新和删除文档等等。

Criteria 是 Spring Data MongoDB 中的一种查询条件构造器,它用于构建查询条件,以便从 MongoDB 数据库中检索文档。通常,Criteria 被用于查询条件的创建,然后与 Query 对象一起使用,用于执行查询。

  1. whereCriteria.where(fieldName) 用于指定要查询的字段名。
  2. iscriteria.is(value) 用于指定字段值的精确匹配。
  3. incriteria.in(values) 用于指定字段值在给定值列表中的匹配。
  4. regexcriteria.regex(pattern) 用于指定正则表达式匹配。
  5. necriteria.ne(value) 用于指定字段值不等于给定值的条件。
  6. lt/le/gt/ge:分别表示小于、小于等于、大于、大于等于。
  7. existscriteria.exists(flag) 用于检查字段是否存在。
  8. and/or/nor:这些方法用于组合多个条件。
List<Criteria> list = new ArrayList<>();
list.add(Criteria.where("stuId").is(stuId));
list.add(Criteria.where("StuName").regex("^.*" + name + ".*$")); //模糊查询
list.add(Criteria.where("stuId").in(stuIds));
list.add(Criteria.where("stuId").exists("11100")); //查stuId为11100的

// and/or/nor
Criteria criteria = new Criteria().andOperator(
    Criteria.where("stuId").is(value1),
    Criteria.where("StuName").regex("pattern"),
    Criteria.where("age").gt(value2)
);
Query query = new Query(criteria);
List<MyEntity> result = mongoTemplate.find(query, MyEntity.class);

二.复杂结构查询

当你Mongo里的数据结构是复杂结构数组套map的形式

其中dataInfo和studentInfo中的map key都为动态id

dataInfo里为map数据

studentInfo为list 列表数据

{
  "_id": ObjectId("653cae5cc13e770843295f30"),
  "StudentTypeEntity": DBRef("StudentTypeEntity", ObjectId("653cae5cc13e770843295f23")),
  "dataInfo": {
    "2a88ec550932ea32c225cbd0dddb29f7": "土木一组",
    "8d1f38297c10ea243c871ffda0537650": NumberLong("1633046400000")
  },
  "studentInfo": [
    {
      "studentId": "111001",
      "studentName": "张三",
      "d134fad9307b02e1c625cf42a90fd9b5": NumberInt("1")
    },
    {
      "studentId": "111002",
      "studentName": "李四",
      "d134fad9307b02e1c625cf42a90fd9b5": NumberInt("2")
    }
  ],
  "updateTime": NumberLong("1698475612570"),
  "createTime": NumberLong("1698475612570")
}

 1.在k-v结构的查找

根据dataInfo的key查给定的值:

list.add(Criteria.where("dataInfo." + key).regex("^.*" + value + ".*$"));
list.add(Criteria.where("dataInfo." + key).is(value));

 对应sql:

db.getCollection("StudentEntity").find({ "$and" : [ { "StudentTypeEntity": DBRef("StudentTypeEntity", ObjectId("653cae5cc13e770843295f23")) }, { "dataInfo.2a88ec550932ea32c225cbd0dddb29f7" : { "$regularExpression" : { "pattern" : "^.*土木.*$", "options" : ""}}} ] })

 2.在数组结构中查找

根据学号等进行查询:

List<StudentQuery.MapInfo> studentInfo = dataQuery.getStudentInfo();
Criteria[] criteriaArray = new Criteria[studentInfo.size()];
for (int i = 0; i < studentInfo.size(); i++) {
StudentQuery.MapInfo item = studentInfo.get(i);
    String key = item.getKey();
    String value = item.getValue();
    if (item.getIsType() != 0) {
        String value1 = "^.*" + value + ".*$";
        criteriaArray[i] = Criteria.where("studentInfo").elemMatch(Criteria.where(key).regex(value1));
    }else {
// 时间就进行精确查询
        criteriaArray[i] = Criteria.where("studentInfo").elemMatch(Criteria.where(key).is(Integer.parseInt(value)));
    }
}

对应查询sql:

db.getCollection("StudentEntity").find({ "$and" : [ { "StudentTypeEntity": DBRef("StudentTypeEntity", ObjectId("653cae5cc13e770843295f23")) },
          { "$and" : [{ "studentInfo" : { "$elemMatch" : { "studentId" : { "$regularExpression" : { "pattern" : "^.*20070015.*$", "options" : ""}}}}}]} ] } )

3.数组中查找多个匹配条件的元素

第一种方法

Criteria.where("studentInfo")
.elemMatch(Criteria.where("studentId").is(studentId)
.and("groups.status").is(true));

 这个查询条件的写法使用了elemMatch来匹配数组中的元素。它会匹配包含指定条件的studentInfo元素。在这里,它会匹配包含studentId等于studentId并且groups里status等于true的元素。

第二种方法

new Criteria().andOperator(
Criteria.where("studentInfo.studentId").is(studentId),
Criteria.where("studentInfo.studentName").is(studentName));

 这个查询条件使用andOperator方法来将多个条件组合在一起,并且直接使用了嵌套的字段路径。由于这两个条件是互相独立的,将会返回同时满足指定条件的元素。它会查找具有以下属性值的文档:

  • "studentInfo.studentId" 等于 studentId
  • "studentInfo.studentName" 等于 studentName

 总结来说,第一种写法使用elemMatch来匹配数组中的元素,可以更灵活地处理数组元素的条件。而第二种写法则直接指定了嵌套字段的路径,适合于直接比较嵌套字段的数值。

注:如果其中一个匹配元素有多个,用elemMatch会返回匹配的一个元素,而使用andOperator方法会返回多个元素。

另:在 MongoDB 中,如果在一个数组中有多个元素满足查询条件,findfindOne 方法只会返回数组中的第一个匹配的元素,而不是所有匹配的元素。因此,如果你需要返回所有匹配的元素,可以使用 find 方法并遍历结果集,或者使用聚合框架中的 $elemMatch 操作符来实现。

三、单个 Criteria 对象 和 Criteria 数组的区别

criteria = Criteria.where("studentInfo").elemMatch(Criteria.where(key).regex(regexValue));和Criteria[] criteriaArray = new Criteria[studentInfo.size()];的区别

  1. 单个 Criteria 对象 vs. Criteria 数组

    • 创建一个 Criteria 对象用于每个条件:Criteria 对象表示单个查询条件。在您的情况下,Criteria[] criteriaArray = new Criteria[authorInfo.size()]; 创建了一个数组,每个元素都是一个独立的查询条件。
    • Criteria.where("authorInfo").elemMatch(Criteria.where(key).regex(regexValue)) 创建了一个查询条件,这个条件可以包含在数组中或独立使用。
  2. 灵活性和维护性

    • 使用 Criteria[] 数组,您可以分别操作每个条件。这种方式更灵活,您可以在条件的级别上进行操作,例如更改或删除单个条件。
    • 使用单个 Criteria 对象时,它表示一个完整的查询条件。在某些情况下,这可能更易于维护,因为条件作为单个对象存储和管理。
  3. 适用场景

    • 使用数组适用于需要动态构建条件的情况,因为它允许您根据数据或逻辑条件创建不同数量的条件。
    • 使用单个 Criteria 对象适用于已知的、确定的条件。如果您的查询条件在编写代码时已知,并且不太可能在运行时更改,那么使用单个条件可能更直观和清晰。

选择其中一种方法取决于您的具体需求和项目结构。如果需要动态地构建多个查询条件,您可能会选择使用数组。如果条件是固定不变的,您可能更倾向于使用单个条件对象。

  • 38
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值