网站是由多个网页组成的吗,网站建设业务平均工资,建设公共网站的手续,锦州建设信息网站CRUD基础操作
Springboot 操作 MongoDB 有两种方式。
第一种方式是采用 Springboot 官方推荐的 JPA 方式#xff0c;这种操作方式#xff0c;使用简单但是灵活性比较差。第二种方式是采用 Spring Data MongoDB 封装的 MongoDB 官方 Java 驱动 MongoTemplate 对 MongoDB 进行…CRUD基础操作
Springboot 操作 MongoDB 有两种方式。
第一种方式是采用 Springboot 官方推荐的 JPA 方式这种操作方式使用简单但是灵活性比较差。第二种方式是采用 Spring Data MongoDB 封装的 MongoDB 官方 Java 驱动 MongoTemplate 对 MongoDB 进行操作这种方式非常灵活能满足绝大部分需求。
本文将采用第二种方式进行介绍
插入文档
MongoTemplate提供了insert()方法用于插入文档示例代码如下
用于插入文档 没指定集合名称时会取Document注解中的集合名称 RunWith(SpringRunner.class)
SpringBootTest
public class PersonServiceTest {Autowiredprivate MongoTemplate mongoTemplate;/*** 插入文档* throws Exception*/Testpublic void insert() throws Exception {Person person new Person();person.setId(1l);person.setUserName(张三);person.setPassWord(123456);person.setCreateTime(new Date());mongoTemplate.insert(person);}
}
自定义集合名称插入文档
RunWith(SpringRunner.class)
SpringBootTest
public class PersonServiceTest {Autowiredprivate MongoTemplate mongoTemplate;/*** 自定义集合插入文档* throws Exception*/Testpublic void insertCustomCollection() throws Exception {Person person new Person();person.setId(1l);person.setUserName(张三);person.setPassWord(123456);person.setCreateTime(new Date());mongoTemplate.insert(person, custom_person);}
}
自定义集合批量插入文档 如果采用批量插入文档必须指定集合名称 RunWith(SpringRunner.class)
SpringBootTest
public class PersonServiceTest {Autowiredprivate MongoTemplate mongoTemplate;/*** 自定义集合批量插入文档* throws Exception*/Testpublic void insertBatch() throws Exception {ListPerson personList new ArrayList();Person person1 new Person();person1.setId(10l);person1.setUserName(张三);person1.setPassWord(123456);person1.setCreateTime(new Date());personList.add(person1);Person person2 new Person();person2.setId(11l);person2.setUserName(李四);person2.setPassWord(123456);person2.setCreateTime(new Date());personList.add(person2);mongoTemplate.insert(personList, custom_person);}
}
存储文档
MongoTemplate提供了save()方法用于存储文档。
在存储文档的时候会通过主键ID进行判断如果存在就更新否则就插入示例代码如下
存储文档如果没有插入否则通过主键ID更新
RunWith(SpringRunner.class)
SpringBootTest
public class PersonServiceTest {Autowiredprivate MongoTemplate mongoTemplate;/*** 存储文档如果没有插入否则更新* throws Exception*/Testpublic void save() throws Exception {Person person new Person();person.setId(13l);person.setUserName(八八);person.setPassWord(123456);person.setAge(40);person.setCreateTime(new Date());mongoTemplate.save(person);}
}
自定义集合存储文档
RunWith(SpringRunner.class)
SpringBootTest
public class PersonServiceTest {Autowiredprivate MongoTemplate mongoTemplate;/*** 自定义集合存储文档* throws Exception*/Testpublic void saveCustomCollection() throws Exception {Person person new Person();person.setId(1l);person.setUserName(张三);person.setPassWord(123456);person.setCreateTime(new Date());mongoTemplate.save(person, custom_person);}
}
更新文档
MongoTemplate提供了updateFirst()和updateMulti()方法用于更新文档示例代码如下
更新文档匹配查询到的文档数据中的第一条数据
RunWith(SpringRunner.class)
SpringBootTest
public class PersonServiceTest {Autowiredprivate MongoTemplate mongoTemplate;/*** 更新文档匹配查询到的文档数据中的第一条数据* throws Exception*/Testpublic void updateFirst() throws Exception {//更新对象Person person new Person();person.setId(1l);person.setUserName(张三123);person.setPassWord(123456);person.setCreateTime(new Date());//更新条件Query query new Query(Criteria.where(id).is(person.getId()));//更新值Update update new Update().set(userName, person.getUserName()).set(passWord, person.getPassWord());//更新查询满足条件的文档数据第一条UpdateResult result mongoTemplate.updateFirst(query,update, Person.class);if(result!null){System.out.println(更新条数 result.getMatchedCount());}}
}
更新文档匹配查询到的文档数据中的所有数据
RunWith(SpringRunner.class)
SpringBootTest
public class PersonServiceTest {Autowiredprivate MongoTemplate mongoTemplate;/*** 更新文档匹配查询到的文档数据中的所有数据* throws Exception*/Testpublic void updateMany() throws Exception {//更新对象Person person new Person();person.setId(1l);person.setUserName(张三);person.setPassWord(123456);person.setCreateTime(new Date());//更新条件Query query new Query(Criteria.where(id).is(person.getId()));//更新值Update update new Update().set(userName, person.getUserName()).set(passWord, person.getPassWord());//更新查询满足条件的文档数据全部UpdateResult result mongoTemplate.updateMulti(query, update, Person.class);if(result!null){System.out.println(更新条数 result.getMatchedCount());}}
}
删除文档
MongoTemplate提供了remove()、findAndRemove()和findAllAndRemove()方法用于删除文档示例代码如下
删除符合条件的所有文档
RunWith(SpringRunner.class)
SpringBootTest
public class PersonServiceTest {Autowiredprivate MongoTemplate mongoTemplate;/*** 删除符合条件的所有文档* throws Exception*/Testpublic void remove() throws Exception {Person person new Person();person.setId(1l);person.setUserName(张三);person.setPassWord(123456);person.setCreateTime(new Date());Query query new Query(Criteria.where(userName).is(person.getUserName()));DeleteResult result mongoTemplate.remove(query, Person.class);System.out.println(删除条数 result.getDeletedCount());}
}
删除符合条件的单个文档并返回删除的文档
RunWith(SpringRunner.class)
SpringBootTest
public class PersonServiceTest {Autowiredprivate MongoTemplate mongoTemplate;/*** 删除符合条件的单个文档并返回删除的文档* throws Exception*/Testpublic void findAndRemove() throws Exception {Person person new Person();person.setId(1l);person.setUserName(张三);person.setPassWord(123456);person.setCreateTime(new Date());Query query new Query(Criteria.where(id).is(person.getId()));Person result mongoTemplate.findAndRemove(query, Person.class);System.out.println(删除的文档数据 result.toString());}
}
删除符合条件的所有文档并返回删除的文档
RunWith(SpringRunner.class)
SpringBootTest
public class PersonServiceTest {Autowiredprivate MongoTemplate mongoTemplate;/*** 删除符合条件的所有文档并返回删除的文档* throws Exception*/Testpublic void findAllAndRemove() throws Exception {Person person new Person();person.setId(1l);person.setUserName(张三);person.setPassWord(123456);person.setCreateTime(new Date());Query query new Query(Criteria.where(id).is(person.getId()));ListPerson result mongoTemplate.findAllAndRemove(query, Person.class);System.out.println(删除的文档数据 result.toString());}
}
查询文档
MongoTemplate提供了非常多的文档查询方法日常开发中用的最多的就是find()方法示例代码如下
查询集合中的全部文档数据
RunWith(SpringRunner.class)
SpringBootTest
public class PersonServiceTest {Autowiredprivate MongoTemplate mongoTemplate;/*** 查询集合中的全部文档数据* throws Exception*/Testpublic void findAll() throws Exception {ListPerson result mongoTemplate.findAll(Person.class);System.out.println(查询结果 result.toString());}
}
查询集合中指定的ID文档数据
RunWith(SpringRunner.class)
SpringBootTest
public class PersonServiceTest {Autowiredprivate MongoTemplate mongoTemplate;/*** 查询集合中指定的ID文档数据* throws Exception*/Testpublic void findById() {long id 1l;Person result mongoTemplate.findById(id, Person.class);System.out.println(查询结果 result.toString());}
}
根据条件查询集合中符合条件的文档返回第一条数据
RunWith(SpringRunner.class)
SpringBootTest
public class PersonServiceTest {Autowiredprivate MongoTemplate mongoTemplate;/*** 根据条件查询集合中符合条件的文档返回第一条数据*/Testpublic void findOne() {String userName 张三;Query query new Query(Criteria.where(userName).is(userName));Person result mongoTemplate.findOne(query, Person.class);System.out.println(查询结果 result.toString());}
}
根据条件查询集合中符合条件的文档
RunWith(SpringRunner.class)
SpringBootTest
public class PersonServiceTest {Autowiredprivate MongoTemplate mongoTemplate;/*** 根据条件查询集合中符合条件的文档*/Testpublic void findByCondition() {String userName 张三;Query query new Query(Criteria.where(userName).is(userName));ListPerson result mongoTemplate.find(query, Person.class);System.out.println(查询结果 result.toString());}
}
根据【AND】关联多个查询条件查询集合中的文档数据
RunWith(SpringRunner.class)
SpringBootTest
public class PersonServiceTest {Autowiredprivate MongoTemplate mongoTemplate;/*** 根据【AND】关联多个查询条件查询集合中的文档数据*/Testpublic void findByAndCondition() {// 创建条件Criteria criteriaUserName Criteria.where(userName).is(张三);Criteria criteriaPassWord Criteria.where(passWord).is(123456);// 创建条件对象将上面条件进行 AND 关联Criteria criteria new Criteria().andOperator(criteriaUserName, criteriaPassWord);// 创建查询对象然后将条件对象添加到其中Query query new Query(criteria);ListPerson result mongoTemplate.find(query, Person.class);System.out.println(查询结果 result.toString());}
}
根据【OR】关联多个查询条件查询集合中的文档数据
RunWith(SpringRunner.class)
SpringBootTest
public class PersonServiceTest {Autowiredprivate MongoTemplate mongoTemplate;/*** 根据【OR】关联多个查询条件查询集合中的文档数据*/Testpublic void findByOrCondition() {// 创建条件Criteria criteriaUserName Criteria.where(userName).is(张三);Criteria criteriaPassWord Criteria.where(passWord).is(123456);// 创建条件对象将上面条件进行 OR 关联Criteria criteria new Criteria().orOperator(criteriaUserName, criteriaPassWord);// 创建查询对象然后将条件对象添加到其中Query query new Query(criteria);ListPerson result mongoTemplate.find(query, Person.class);System.out.println(查询结果 result.toString());}
}根据【IN】关联多个查询条件查询集合中的文档数据
RunWith(SpringRunner.class)
SpringBootTest
public class PersonServiceTest {Autowiredprivate MongoTemplate mongoTemplate;/*** 根据【IN】关联多个查询条件查询集合中的文档数据*/Testpublic void findByInCondition() {// 设置查询条件参数ListLong ids Arrays.asList(1l, 10l, 11l);// 创建条件Criteria criteria Criteria.where(id).in(ids);// 创建查询对象然后将条件对象添加到其中Query query new Query(criteria);ListPerson result mongoTemplate.find(query, Person.class);System.out.println(查询结果 result.toString());}
}
根据【逻辑运算符】查询集合中的文档数据
RunWith(SpringRunner.class)
SpringBootTest
public class PersonServiceTest {Autowiredprivate MongoTemplate mongoTemplate;/*** 根据【逻辑运算符】查询集合中的文档数据*/Testpublic void findByOperator() {// 设置查询条件参数int min 20;int max 35;Criteria criteria Criteria.where(age).gt(min).lte(max);// 创建查询对象然后将条件对象添加到其中Query query new Query(criteria);ListPerson result mongoTemplate.find(query, Person.class);System.out.println(查询结果 result.toString());}
}
根据【正则表达式】查询集合中的文档数据
RunWith(SpringRunner.class)
SpringBootTest
public class PersonServiceTest {Autowiredprivate MongoTemplate mongoTemplate;/*** 根据【正则表达式】查询集合中的文档数据*/Testpublic void findByRegex() {// 设置查询条件参数String regex ^张*;Criteria criteria Criteria.where(userName).regex(regex);// 创建查询对象然后将条件对象添加到其中Query query new Query(criteria);ListPerson result mongoTemplate.find(query, Person.class);System.out.println(查询结果 result.toString());}
}
根据条件查询集合中符合条件的文档获取其文档列表并排序
RunWith(SpringRunner.class)
SpringBootTest
public class PersonServiceTest {Autowiredprivate MongoTemplate mongoTemplate;/*** 根据条件查询集合中符合条件的文档获取其文档列表并排序*/Testpublic void findByConditionAndSort() {String userName 张三;Query query new Query(Criteria.where(userName).is(userName)).with(Sort.by(age));ListPerson result mongoTemplate.find(query, Person.class);System.out.println(查询结果 result.toString());}
}
根据单个条件查询集合中的文档数据并按指定字段进行排序与限制指定数目
RunWith(SpringRunner.class)
SpringBootTest
public class PersonServiceTest {Autowiredprivate MongoTemplate mongoTemplate;/*** 根据单个条件查询集合中的文档数据并按指定字段进行排序与限制指定数目*/Testpublic void findByConditionAndSortLimit() {String userName 张三;//从第一行开始查询2条数据返回Query query new Query(Criteria.where(userName).is(userName)).with(Sort.by(createTime)).limit(2).skip(1);ListPerson result mongoTemplate.find(query, Person.class);System.out.println(查询结果 result.toString());}
}
统计集合中符合【查询条件】的文档【数量】
RunWith(SpringRunner.class)
SpringBootTest
public class PersonServiceTest {Autowiredprivate MongoTemplate mongoTemplate;/*** 统计集合中符合【查询条件】的文档【数量】*/Testpublic void countNumber() {// 设置查询条件参数String regex ^张*;Criteria criteria Criteria.where(userName).regex(regex);// 创建查询对象然后将条件对象添加到其中Query query new Query(criteria);long count mongoTemplate.count(query, Person.class);System.out.println(统计结果 count);}
}
查询指定字段返回 Testpublic void test1() {Query query Query.query(Criteria.where(userId).is(1L));query.fields().include(pid).exclude(_id);/*Expected to read Document Document{{pid2031}} into type class java.lang.Integer but didnt find a PersistentEntity for the latter!* {_id5fae53927e52992e78a3aecd, pid2031}*{_id5fae53927e52992e78a3aed9, pid2032}*{_id5fae53927e52992e78a3aee5, pid2033}* {pid2033}* {pid2034}* {pid2035}*/ListObject result mongoTemplate.find(query, Object.class, quanzi_publish);result.forEach(System.out::println);}通过query点fields 可以通过 include 指定需要返回的字段。可以链式编程。
exclude排除需要的字段。 因为如果指定需要的字段。不排除_id 的话查询的数据会默认包含_id
{_id5fae53927e52992e78a3aecd, pid2031} 所以我这里做了排除。
最后查询的结果是 {pid2033} 此时我的pid 是一个Long 类型的数据。但是不能用
Long.class 去解析。只能用Object.clss 因为 {pid2033} 虽然只有一个字段。但是从mongodb查询出来的应该是一个json对象。对象的属性只有一个。没有去看mongodb底层。但应该是做了json的解析。
Test
public void test2() {Query query Query.query(Criteria.where(userId).is(1L));ListMyLong result mongoTemplate.find(query, MyLong.class, quanzi_publish);ListLong pids result.stream().map(MyLong::getPid).collect(Collectors.toList());pids.forEach(System.out::println);
}class MyLong {private Long pid;public Long getPid() {return pid;}public void setPid(Long pid) {this.pid pid;}Overridepublic String toString() {return MyLong{ pid pid };}
}既然是解析json 。我自己定义了一个类。同样的属性去接。然后用stream 流转为了long类型的list集合。这样做感觉也挺麻烦。但是如果集合字段特别多的话。这样应该能提升一些性能。毕竟如果直接读取整个集合也是需要遍历。然后提取出id 到一个新集合。步骤差不多。这样只是从mongodb只读取了需要的数据。
查询某字段在MongoDB中是否存在并返回一条查询记录
String field F1_0909;
Query query new Query();
query.fields().include(field);
query.addCriteria(new Criteria(filed).exists(true));
Map map mongoTemplate.findOne(query, Map.class, collectionName);排序
Test
public void findListStudentSort() {// 排序Query query new Query();query.with(Sort.by(Sort.Direction.DESC, age));ListStudent students mongoTemplate.find(query, Student.class);// students】】】 students);}分页
Test
public void findFenYeList() {// 分页// 设置分页参数Query query new Query();int currentPage 2;// 0,1相同int pageSize 2;// 设置分页信息query.limit(pageSize);query.skip(pageSize * (currentPage - 1));// query.addCriteria(Criteria.where(clazzName).regex(天));ListClazz clazzes mongoTemplate.find(query, Clazz.class);// clazzs】】】 clazzes);
}
Test
public void findZongHe() {// 分页范围模糊查询排序// 拼装查询信息Query query new Query();query.addCriteria(Criteria.where(age).gte(6).lte(18));query.with(Sort.by(Sort.Direction.ASC, age));query.addCriteria(Criteria.where(name).regex(小));// 模糊查询名字Long count mongoTemplate.count(query, Student.class);// 查询总记录数ListStudent list mongoTemplate.find(query, Student.class);}/ 将筛选条件放入管道中
Aggregation aggregation Aggregation.newAggregation(lookup,Aggregation.match(criteria),Aggregation.group(startSolitaireId) // 分组的字段.first(startSolitaireId).as(startSolitaireId) // 映射的字段 并取别名.first(userId).as(userId).first(interact).as(interact).first(createTime).as(createTime).first(startVO).as(startVO),Aggregation.sort(Sort.Direction.DESC,createTime), // 排序Aggregation.skip((long) page.getCurrent() * page.getSize()),Aggregation.limit(page.getSize())); // 分页
MongoDB 聚合操作
聚合表达式
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.AggregationOperation;
import org.springframework.data.mongodb.core.aggregation.AggregationResults;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.Map;/*** 聚合表达式 $group** author mydlq*/
Slf4j
Service
public class AggregateGroupService {/*** 设置集合名称*/private static final String COLLECTION_NAME users;Resourceprivate MongoTemplate mongoTemplate;/*** 使用管道操作符 $group 结合 $count 方法进行聚合统计** return 聚合结果*/public Object aggregationGroupCount() {// 使用管道操作符 $group 进行分组然后统计各个组的文档数量AggregationOperation group Aggregation.group(age).count().as(numCount);// 将操作加入到聚合对象中Aggregation aggregation Aggregation.newAggregation(group);// 执行聚合查询AggregationResultsMap results mongoTemplate.aggregate(aggregation, COLLECTION_NAME, Map.class);for (Map result : results.getMappedResults()) {log.info({}, result);}return results.getMappedResults();}/*** 使用管道操作符 $group 结合表达式操作符 $max 进行聚合统计** return 聚合结果*/public Object aggregationGroupMax() {// 使用管道操作符 $group 进行分组然后统计各个组文档某字段最大值AggregationOperation group Aggregation.group(sex).max(salary).as(salaryMax);// 将操作加入到聚合对象中Aggregation aggregation Aggregation.newAggregation(group);// 执行聚合查询AggregationResultsMap results mongoTemplate.aggregate(aggregation, COLLECTION_NAME, Map.class);for (Map result : results.getMappedResults()) {log.info({}, result);}return results.getMappedResults();}/*** 使用管道操作符 $group 结合表达式操作符 $min 进行聚合统计** return 聚合结果*/public Object aggregationGroupMin() {// 使用管道操作符 $group 进行分组然后统计各个组文档某字段最小值AggregationOperation group Aggregation.group(sex).min(salary).as(salaryMin);// 将操作加入到聚合对象中Aggregation aggregation Aggregation.newAggregation(group);// 执行聚合查询AggregationResultsMap results mongoTemplate.aggregate(aggregation, COLLECTION_NAME, Map.class);for (Map result : results.getMappedResults()) {log.info({}, result);}return results.getMappedResults();}/*** 使用管道操作符 $group 结合表达式操作符 $sum 进行聚合统计** return 聚合结果*/public Object aggregationGroupSum() {// 使用管道操作符 $group 进行分组然后统计各个组文档某字段值合计AggregationOperation group Aggregation.group(sex).sum(salary).as(salarySum);// 将操作加入到聚合对象中Aggregation aggregation Aggregation.newAggregation(group);// 执行聚合查询AggregationResultsMap results mongoTemplate.aggregate(aggregation, COLLECTION_NAME, Map.class);for (Map result : results.getMappedResults()) {log.info({}, result);}return results.getMappedResults();}/*** 使用管道操作符 $group 结合表达式操作符 $avg 进行聚合统计** return 聚合结果*/public Object aggregationGroupAvg() {// 使用管道操作符 $group 进行分组然后统计各个组文档某字段值平均值AggregationOperation group Aggregation.group(sex).avg(salary).as(salaryAvg);// 将操作加入到聚合对象中Aggregation aggregation Aggregation.newAggregation(group);// 执行聚合查询AggregationResultsMap results mongoTemplate.aggregate(aggregation, COLLECTION_NAME, Map.class);for (Map result : results.getMappedResults()) {log.info({}, result);}return results.getMappedResults();}/*** 使用管道操作符 $group 结合表达式操作符 $first 获取每个组的包含某字段的文档的第一条数据** return 聚合结果*/public Object aggregationGroupFirst() {// 先对数据进行排序然后使用管道操作符 $group 进行分组最后统计各个组文档某字段值第一个值AggregationOperation sort Aggregation.sort(Sort.by(salary).ascending());AggregationOperation group Aggregation.group(sex).first(salary).as(salaryFirst);// 将操作加入到聚合对象中Aggregation aggregation Aggregation.newAggregation(sort, group);// 执行聚合查询AggregationResultsMap results mongoTemplate.aggregate(aggregation, COLLECTION_NAME, Map.class);for (Map result : results.getMappedResults()) {log.info({}, result);}return results.getMappedResults();}/*** 使用管道操作符 $group 结合表达式操作符 $last 获取每个组的包含某字段的文档的最后一条数据** return 聚合结果*/public Object aggregationGroupLast() {// 先对数据进行排序然后使用管道操作符 $group 进行分组最后统计各个组文档某字段值第最后一个值AggregationOperation sort Aggregation.sort(Sort.by(salary).ascending());AggregationOperation group Aggregation.group(sex).last(salary).as(salaryLast);// 将操作加入到聚合对象中Aggregation aggregation Aggregation.newAggregation(sort, group);// 执行聚合查询AggregationResultsMap results mongoTemplate.aggregate(aggregation, COLLECTION_NAME, Map.class);for (Map result : results.getMappedResults()) {log.info({}, result);}return results.getMappedResults();}/*** 使用管道操作符 $group 结合表达式操作符 $push 获取某字段列表** return 聚合结果*/public Object aggregationGroupPush() {// 先对数据进行排序然后使用管道操作符 $group 进行分组然后以数组形式列出某字段的全部值AggregationOperation push Aggregation.group(sex).push(salary).as(salaryFirst);// 将操作加入到聚合对象中Aggregation aggregation Aggregation.newAggregation(push);// 执行聚合查询AggregationResultsMap results mongoTemplate.aggregate(aggregation, COLLECTION_NAME, Map.class);for (Map result : results.getMappedResults()) {log.info({}, result);}return results.getMappedResults();}}聚合管道操作符
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.AggregationOperation;
import org.springframework.data.mongodb.core.aggregation.AggregationResults;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.Map;Slf4j
Service
public class AggregatePipelineService {/*** 设置集合名称*/private static final String COLLECTION_NAME users;Resourceprivate MongoTemplate mongoTemplate;/*** 使用 $group 和 $match 聚合,先使用 $match 过滤文档然后再使用 $group 进行分组** return 聚合结果*/public Object aggregateGroupMatch() {// 设置聚合条件先使用 $match 过滤岁数大于 25 的用户然后按性别分组统计每组用户工资最高值AggregationOperation match Aggregation.match(Criteria.where(age).lt(25));AggregationOperation group Aggregation.group(sex).max(salary).as(sexSalary);// 将操作加入到聚合对象中Aggregation aggregation Aggregation.newAggregation(match, group);// 执行聚合查询AggregationResultsMap results mongoTemplate.aggregate(aggregation, COLLECTION_NAME, Map.class);for (Map result : results.getMappedResults()) {log.info({}, result);}return results.getMappedResults();}/*** 使用 $group 和 $sort 聚合,先使用 $group 进行分组然后再使用 $sort 排序** return 聚合结果*/public Object aggregateGroupSort() {// 设置聚合条件按岁数分组然后统计每组用户工资最大值和用户数按每组用户工资最大值升序排序AggregationOperation group Aggregation.group(age).max(salary).as(ageSalary).count().as(ageCount);AggregationOperation sort Aggregation.sort(Sort.by(ageSalary).ascending());// 将操作加入到聚合对象中Aggregation aggregation Aggregation.newAggregation(group, sort);// 执行聚合查询AggregationResultsMap results mongoTemplate.aggregate(aggregation, COLLECTION_NAME, Map.class);for (Map result : results.getMappedResults()) {log.info({}, result);}return results.getMappedResults();}/*** 使用 $group 和 $limit 聚合,先使用 $group 进行分组然后再使用 $limit 限制一定数目文档** return 聚合结果*/public Object aggregateGroupLimit() {// 设置聚合条件先按岁数分组然后求每组用户的工资总数、最大值、最小值、平均值限制只能显示五条AggregationOperation group Aggregation.group(age).sum(salary).as(sumSalary).max(salary).as(maxSalary).min(salary).as(minSalary).avg(salary).as(avgSalary);AggregationOperation limit Aggregation.limit(5L);// 将操作加入到聚合对象中Aggregation aggregation Aggregation.newAggregation(group, limit);// 执行聚合查询AggregationResultsMap results mongoTemplate.aggregate(aggregation, COLLECTION_NAME, Map.class);for (Map result : results.getMappedResults()) {log.info({}, result);}return results.getMappedResults();}/*** 使用 $group 和 $skip 聚合,先使用 $group 进行分组然后再使用 $skip 跳过一定数目文档** return 聚合结果*/public Object aggregateGroupSkip() {// 设置聚合条件先按岁数分组然后求每组用户的工资总数、最大值、最小值、平均值跳过前 2 条AggregationOperation group Aggregation.group(age).sum(salary).as(sumSalary).max(salary).as(maxSalary).min(salary).as(minSalary).avg(salary).as(avgSalary);AggregationOperation limit Aggregation.skip(2L);// 将操作加入到聚合对象中Aggregation aggregation Aggregation.newAggregation(group, limit);// 执行聚合查询AggregationResultsMap results mongoTemplate.aggregate(aggregation, COLLECTION_NAME, Map.class);for (Map result : results.getMappedResults()) {log.info({}, result);}return results.getMappedResults();}/*** 使用 $group 和 $project 聚合,先使用 $group 进行分组然后再使用 $project 限制显示的字段** return 聚合结果*/public Object aggregateGroupProject() {// 设置聚合条件,按岁数分组然后求每组用户工资最大值、最小值然后使用 $project 限制值显示 salaryMax 字段AggregationOperation group Aggregation.group(age).max(salary).as(maxSalary).min(salary).as(minSalary);AggregationOperation project Aggregation.project(maxSalary);// 将操作加入到聚合对象中Aggregation aggregation Aggregation.newAggregation(group, project);// 执行聚合查询AggregationResultsMap results mongoTemplate.aggregate(aggregation, COLLECTION_NAME, Map.class);for (Map result : results.getMappedResults()) {log.info({}, result);}return results.getMappedResults();}/*** 使用 $group 和 $unwind 聚合,先使用 $project 进行分组然后再使用 $unwind 拆分文档中的数组为一条新文档记录** return 聚合结果*/public Object aggregateProjectUnwind() {// 设置聚合条件设置显示name、age、title字段然后将结果中的多条文档按 title 字段进行拆分AggregationOperation project Aggregation.project(name, age, title);AggregationOperation unwind Aggregation.unwind(title);// 将操作加入到聚合对象中Aggregation aggregation Aggregation.newAggregation(project, unwind);// 执行聚合查询AggregationResultsMap results mongoTemplate.aggregate(aggregation, COLLECTION_NAME, Map.class);for (Map result : results.getMappedResults()) {log.info({}, result);}return results.getMappedResults();}}聚合管道操作符
$project 可以从文档中选择想要的字段和不想要的字段指定的字段可以是来自输入文档或新计算字段的现有字段 也可以通过管道表达式进行一些复杂的操作例如数学操作日期操作字符串操作逻辑操作。** m a t c h ∗ ∗ 用于过滤数据只输出符合条件的文档。 match** 用于过滤数据只输出符合条件的文档。 match∗∗用于过滤数据只输出符合条件的文档。match使用MongoDB的标准查询操作。$limit 用来限制MongoDB聚合管道返回的文档数。$skip 在聚合管道中跳过指定数量的文档并返回余下的文档。$unwind 将文档中的某一个数组类型字段拆分成多条每条包含数组中的一个值。$group 将集合中的文档分组可用于统计结果。$sort 将输入文档排序后输出。
关联查询
LookupOperation这个类就是用来进行联表操作的类具体方法
newLookup 用来创建一个LookupOperation.Builderfrom 要连接哪张表类似Mysql的JOINlocalField主表哪个字段去连接指明出来from表参考主表的哪个字段foreignField form连接的那个表哪个字段关联as 从表结果集名最后会在主表多出这个自定义列默认List理解为as一个别名会把从表的数据以数组的形式在as字段内
表结构
Item
{_id: 111,sActiveId: 222,sName: 333,sIcon: 444,sDes: 555,iItemType: NumberInt(1),sValue: 666,iProperty: [0],iDuration: NumberInt(77),createTime: ISODate(2022-03-23T08:13:19.694Z),updateTime: ISODate(2022-03-23T08:13:19.694Z),iStatus: NumberInt(0)
}
ItemUser
{_id: 222,sActiveId: 333,sItemId: 111,sUserId: 444,iCount: NumberInt(4)
}生成管道以下是ItemUser 是主表****Item是从表
// 联表
LookupOperation lookupOperation LookupOperation.newLookup()// 连接哪张表.from(Item)// 主表哪个字段连接.localField(sItemId)// 从表哪个字段关联.foreignField(_id)// 从表结果集名 最后会在主表多出这个自定义列 默认List.as(item);
// 查询(只能是主表的字段取别名字段不可以例如item.sName 是不可以的)
Criteria criteria Criteria.where(sUserId).is(444);
// 类似mysql的select列 如果要用从表的列 就as自定义列名点属性
ProjectionOperation projectionOperation Aggregation.project(id, sItemId, iCount, item.iDuration, item.sName, item.sIcon, item.sDes, item.iItemType);
// 建立管道
Aggregation aggregation Aggregation.newAggregation(// 联表lookupOperation,// 查询Aggregation.match(criteria),// 将某个集合列拆成字段添加主表Aggregation.unwind(item),// 排序Aggregation.sort(Sort.Direction.DESC, createTime),// selectprojectionOperation
);AggregationResultsJSONObject aggregationResults mongoTemplate.aggregate(aggregation, ItemUser, JSONObject.class);
ListJSONObject result aggregationResults.getMappedResults();
前面提到as会在主表新增个列列里内容是数组Aggregation.unwind(“item”)的作用就是把as列里数组拆掉通过ProjectionOperation 加在主表自定义字段中
实际的联查写法 //多表关联的条件声明LookupOperation cusAndInfoLookup LookupOperation.newLookup().from(adrs).//1.副表表名字localField(_id).//2.主表的关联字段foreignField(adrsId).//3.副表的关联字段as(adrs);//4.建议和1一致结果的别名//关联多张表就写多个
// LookupOperation cusAndInfoLookup1 LookupOperation.newLookup().
// from(adrs).
// localField(_id).
// foreignField(adrsId).
// as(adrs);//多表的关联条件查询条件均传入到此Aggregation aggregation Aggregation.newAggregation(cusAndInfoLookup,
// cusAndInfoLookup1,
// Aggregation.match(Criteria.where(_id).lte(2)),//5.此作用处下文解释
// Aggregation.unwind(adrs),//筛选条件筛选主表的字段直接写副表则是别名.字段名Aggregation.match(Criteria.where(adrs.adrsId).is(1)));//5.此处填写主表名称AggregationResultsJSONObject results mongoTemplate.aggregate(aggregation, tab_map, JSONObject.class);ListJSONObject objectList results.getMappedResults();for (JSONObject json : objectList) {System.out.println(json);}
unwind的作用默认关联查询出现多个关联值时结果会以array返回例如一个用户有多个收货地址则会返回
{id:1,adrs:[{adrs1},{adrs2}]}
unwind(adrs)返回数据成为常见的sql返回多条
{id:1,adrs:{adrs1}}
{id:1,adrs:{adrs2}}
分组两表三表联查
####分组两表三表联查###########################################################
import com.csw.mongodbspringbootdemo.entity.Chair;
import com.csw.mongodbspringbootdemo.entity.Desk;
import com.csw.mongodbspringbootdemo.entity.Room;
import com.mongodb.BasicDBObject;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.AggregationOperation;
import org.springframework.data.mongodb.core.aggregation.AggregationResults;
import org.springframework.data.mongodb.core.aggregation.LookupOperation;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.test.context.junit4.SpringRunner;import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.UUID;SpringBootTest
RunWith(SpringRunner.class)
public class RoomDeskRecommend {Autowiredprivate MongoTemplate mongoTemplate;Testpublic void saveRoom() {// 添加房间Room room new Room();room.setName(空房间2);room.setUnitCode(UUID.randomUUID().toString());mongoTemplate.save(room);Room room2 new Room();room2.setName(空房间1);room2.setUnitCode(UUID.randomUUID().toString());mongoTemplate.save(room2);}Testpublic void saveDesk() {// 添加桌子String roomName 光明房间;String deskName 5号桌子;Query query new Query(Criteria.where(name).is(roomName));Room room mongoTemplate.findOne(query, Room.class);Desk desk new Desk();desk.setName(deskName);assert room ! null;desk.setUnitCode(room.getUnitCode());mongoTemplate.save(desk);System.out.println(room);Query query2 new Query(Criteria.where(name).is(deskName));Desk desk2 mongoTemplate.findOne(query2, Desk.class);System.out.println(desk2);}Testpublic void groupBy() {// groupListAggregationOperation aggs new ArrayList();// aggs.add(Aggregation.match(Criteria.where(name).is(log)));aggs.add(Aggregation.group(name).count().as(count));aggs.add(Aggregation.project().and(_id).as(name).and(count).as(count));Aggregation agg Aggregation.newAggregation(aggs);AggregationResultsMap results mongoTemplate.aggregate(agg, Desk.class, Map.class);for (Map result : results) {System.out.println(result);}}Testpublic void findMoreTable() {// 两表联查LookupOperation lookupOperation LookupOperation.newLookup().from(room). // 关联表名localField(unitCode). // 主关联字段foreignField(unitCode).// 从表关联字段对应的次表字段as(rooms);// 查询结果集合名Criteria ordercri Criteria.where(rooms).not().size(0);// 只查询有宠物的人// ordercri.and(age).gte(1).lte(5);//只查询1岁到5岁的宠物AggregationOperation matchZi Aggregation.match(ordercri);Aggregation aggregation Aggregation.newAggregation(lookupOperation, matchZi);// 排序ListMap results mongoTemplate.aggregate(aggregation, desk, Map.class).getMappedResults(); // 查询出的结果集为BasicDBObject类型for (Map result : results) {System.out.println(result);}}Testpublic void findMoreTable2() {// 两表联查LookupOperation lookupOperation LookupOperation.newLookup().from(desk). // 关联表名localField(unitCode). // 主关联字段foreignField(unitCode).// 从表关联字段对应的次表字段as(desks);// 查询结果集合名Criteria ordercri Criteria.where(desks).not().size(0);// 只查询有宠物的人// ordercri.and(age).gte(1).lte(5);//只查询1岁到5岁的宠物AggregationOperation matchZi Aggregation.match(ordercri);Aggregation aggregation Aggregation.newAggregation(lookupOperation, matchZi);// 排序ListMap results mongoTemplate.aggregate(aggregation, room, Map.class).getMappedResults(); // 查询出的结果集为BasicDBObject类型for (Map result : results) {System.out.println(result);}}Testpublic void findMoreTableZongHe() {// 两表联查int pageNumber 2;// 0,1相同int pageSize 2;// 拼装关联信息LookupOperation lookupOperation LookupOperation.newLookup().from(room). // 关联表名localField(unitCode). // 主关联字段foreignField(unitCode).// 从表关联字段对应的次表字段as(ClazzStudents);// 查询结果集合名// 拼装具体查询信息// 次表Criteria ordercri Criteria.where(ClazzStudents).not().size(0);// 只查询有宠物的人// ordercri.and(age).gte(1).lte(5);//只查询1岁到5岁的宠物AggregationOperation matchZi Aggregation.match(ordercri);// 主表Criteria qqq Criteria.where(name).regex(号);// 只查询名字中带有文的人AggregationOperation matchFu Aggregation.match(qqq);// 分页查询Aggregation aggregation Aggregation.newAggregation(matchFu, lookupOperation, matchZi,Aggregation.sort(Sort.Direction.DESC, name),Aggregation.skip(pageSize 1 ? (pageNumber - 1) * pageSize : 0), Aggregation.limit(pageSize));// 排序// Aggregation.skip(pageable.getPageNumber()1?(pageable.getPageNumber()-1)*pageable.getPageSize():0),//pagenumber// 分页/** Aggregation.skip(pageSize1?(pageNumber-1)*pageSize:0);* Aggregation.limit(pageSize);*/// Aggregation.group(name);// 总数查询Aggregation counts Aggregation.newAggregation(matchFu, lookupOperation, matchZi);int count mongoTemplate.aggregate(counts, Desk.class, BasicDBObject.class).getMappedResults().size();System.out.println(【count】 count);ListMap results mongoTemplate.aggregate(aggregation, desk, Map.class).getMappedResults(); // 查询出的结果集为BasicDBObject类型for (Map result : results) {System.out.println(result);}}Testpublic void saveChair() {// 添加椅子String roomName 光明房间;String chairName 1号椅子;Query query new Query(Criteria.where(name).is(roomName));Room room mongoTemplate.findOne(query, Room.class);Chair chair new Chair();chair.setName(chairName);assert room ! null;chair.setUnitCode(room.getUnitCode());mongoTemplate.save(chair);}Testpublic void findMoreTable3_0() {// 三表联查测试第一个表关联第二个人表关联字段1第一个表关联第三个表关联字段1LookupOperation lookupOperation LookupOperation.newLookup().from(desk). // 关联表名localField(unitCode). // 主关联字段foreignField(unitCode).// 从表关联字段对应的次表字段as(desks);// 查询结果集合名Criteria ordercri Criteria.where(desks).not().size(0);// 只查询有宠物的人// ordercri.and(age).gte(1).lte(5);//只查询1岁到5岁的宠物AggregationOperation matchZi Aggregation.match(ordercri);LookupOperation lookupOperation2 LookupOperation.newLookup().from(chair). // 关联表名localField(unitCode). // 主关联字段foreignField(unitCode).// 从表关联字段对应的次表字段as(chairs);// 查询结果集合名Criteria ordercri2 Criteria.where(chairs).not().size(0);// 只查询有宠物的人// ordercri.and(age).gte(1).lte(5);//只查询1岁到5岁的宠物AggregationOperation matchZi2 Aggregation.match(ordercri2);Aggregation aggregation Aggregation.newAggregation(lookupOperation, matchZi, lookupOperation2, matchZi2);// 排序ListMap results mongoTemplate.aggregate(aggregation, room, Map.class).getMappedResults(); // 查询出的结果集为BasicDBObject类型for (Map result : results) {System.out.println(result);}}// 数据模拟Testpublic void findMoreTable3_1() {// 三表联查测试第一个表关联第二个人表关联字段1第一个表关联第三个表关联字段2LookupOperation lookupOperation LookupOperation.newLookup().from(desk). // 关联表名localField(unitCode). // 主关联字段foreignField(unitCode).// 从表关联字段对应的次表字段as(desks);// 查询结果集合名Criteria ordercri Criteria.where(desks).not().size(0);// 只查询有宠物的人// ordercri.and(age).gte(1).lte(5);//只查询1岁到5岁的宠物AggregationOperation matchZi Aggregation.match(ordercri);LookupOperation lookupOperation2 LookupOperation.newLookup().from(chair). // 关联表名localField(lastCode). // 主关联字段foreignField(lastCode).// 从表关联字段对应的次表字段as(chairs);// 查询结果集合名Criteria ordercri2 Criteria.where(chairs).not().size(0);// 只查询有宠物的人// ordercri.and(age).gte(1).lte(5);//只查询1岁到5岁的宠物AggregationOperation matchZi2 Aggregation.match(ordercri2);Aggregation aggregation Aggregation.newAggregation(lookupOperation, matchZi, lookupOperation2, matchZi2);// 排序ListMap results mongoTemplate.aggregate(aggregation, room, Map.class).getMappedResults(); // 查询出的结果集为BasicDBObject类型for (Map result : results) {System.out.println(result);}}// 数据模拟Testpublic void findMoreTable3_3() {// 三表联查测试第一个表关联第二个人表关联字段1第二个表关联第三个表关联字段2LookupOperation lookupOperation LookupOperation.newLookup().from(room). // 关联表名localField(unitCode). // 主关联字段foreignField(unitCode).// 从表关联字段对应的次表字段as(rooms);// 查询结果集合名Criteria ordercri Criteria.where(rooms).not().size(0);// 只查询有宠物的人// ordercri.and(age).gte(1).lte(5);//只查询1岁到5岁的宠物AggregationOperation matchZi Aggregation.match(ordercri);LookupOperation lookupOperation2 LookupOperation.newLookup().from(chair). // 关联表名localField(rooms.lastCode). // 主关联字段foreignField(lastCode).// 从表关联字段对应的次表字段as(chairs);// 查询结果集合名Criteria ordercri2 Criteria.where(chairs).not().size(0);// 只查询有宠物的人// ordercri.and(age).gte(1).lte(5);//只查询1岁到5岁的宠物AggregationOperation matchZi2 Aggregation.match(ordercri2);Aggregation aggregation Aggregation.newAggregation(lookupOperation, matchZi, lookupOperation2, matchZi2);// 排序ListMap results mongoTemplate.aggregate(aggregation, desk, Map.class).getMappedResults(); // 查询出的结果集为BasicDBObject类型for (Map result : results) {System.out.println(result);}}
常用函数
使用前我们先来了解一下常用的函数
Aggregation.group() : 聚合函数将某个字段或者某个数组作为分组统计的依据,在group的基础上又扩展出以下函数 sum() : 求和max() : 获取最大值min() : 获取最小值avg() : 获取平均值count() : 统计条目数first () : 获取group by 后的某个字段的首个值last() : 获取 group by 后的某个字段的最后一个值push() : 在结果文档中插入值到一个数组中addToSet() : 在结果文档中插入值到一个数组中但不创建副本(作为集合)。 Aggregation.match() : 过滤函数主要存储过滤数据的条件输出符合条件的记录Aggregation.project(): 修改数据结构函数,将前面管道中的获取的字段进行重名,增加修改字段等操作。Aggregation.unwind()将文档中的某一个数组类型字段拆分成多条每条包含数组中的一个值。当preserveNullAndEmptyArrays为true时将包括字段为null空或者缺失的数据;Aggregation.sort(): 排序函数将上级管道的内容按照某个字段进行排序并且输出。值为1升、-1降。sort一般放在group后,也就是说得到结果后再排序如果先排序再分组没什么意义;Aggregation.limit(): 限制输出函数将聚合返回的内容限定在某个条目之内。通常作为页面大小Aggregation.skip(): 跳过指定数量的条目再开始返回数据的函数通常和sort()limit()配合实现数据翻页查询等操作。Aggregation.lookup(): 连表查询将被关联集合添加到执行操作的集合中。
实例
用accountId和status做group操作
Copymongodb
db.getCollection(mro_fn_subscribes).aggregate([{$group:{_id:{_id:$accountId, status: $status },count:{$sum: NumberInt(1)},statusSum:{$sum: $status},codeAvg:{$avg:$fnCode},codeMax:{$max:$fnCode},codeMin:{$min:$fnCode},codeFirst:{$first:$fnCode},codeLast:{$last:$fnCode},}}
])java:
Aggregation aggregation Aggregation.newAggregation(Aggregation.group(accountId, status).count().as(count).sum(status).as(statusSum).avg(fnCode).as(codeAvg).max(fnCode).as(codeMax).min(fnCode).as(codeMin).first(fnCode).as(codeFirst).last(fnCode).as(codeLast)
);match管道过滤:
Copymongodb
db.getCollection(mro_fn_subscribes).aggregate({$match:{userId:a}}
)java:
Aggregation aggregation Aggregation.newAggregation(Aggregation.match(new Criteria().and(userId).is(a)
);project筛选字段:
Copymongo:
db.getCollection(mro_fn_subscribes).aggregate([{$group : {_id : $_id, num : {$sum : $num}, firstName : {$first : $name}, lastName : {$last : $name}}}, {$project : {_id : 1, num : 1, firstName : 1, name : $lastName}}
])java:
// 初始化聚合
Aggregation aggregation Aggregation.newAggregation(Aggregation.group(new String[] {_id}).sum(num).as(num).first(name).as(firstName).last(name).as(lastName),Aggregation.project(_id, num, firstName).and(lastName).as(name) // 重新命名字段
);unwind拆分数组
Copymongo:
db.col.aggregate({$match:{userid:a}}, {$unwind:{path:$items, includeArrayIndex: arrayIndex}}
)java:
Aggregation aggregation Aggregation.newAggregation(Aggregation.match(new Criteria().and(userId).is(a),Aggregation.unwind(items,true)
);sort skip limit处理数据:
CopyMongo
db.getCollection(mro_fn_subscribes).aggregate([{$group : {_id:{_id:$accountId, status: $status } }}, {$sort : {num : -1}}, {$skip : NumberInt(10)}, {$limit : NumberInt(2)}
]
)
Java:
Aggregation aggregation Aggregation.newAggregation(Aggregation.group(accountId, status)Aggregation.sort(Direction.DESC, num), //将num降序Aggregation.skip(10), //从第10条记录开始Aggregation.limit(2) //取两条数据
);lookup多表关联查询:
Copy# Mongo
db.getCollection(mro_accounts).aggregate([{$lookup: {from:mro_profiles, # 被关联表名localField:userName, # 主表mro_accounts中用于关联的字段foreignField:mobile, # 被关联表mro_profiles中用于关联的字段as:profileDoc # 被关联的表的别名}}
])
# Java
Aggregation aggregation Aggregation.newAggregation(Aggregation.lookup(mro_profiles, userName, mobile, profileDoc) //分别对应from, localField, foreignField, as
);获取查询结果
在创建好Aggregation对象之后,再用 mongotemplate.aggregate(aggregation, “mro_fn_subscribes”, Fnsubscribe.class).getMappedResults() 获取查询的对象列表
日期字符串转ISO日期格式mogodb
public static void main(String[] args) {ZoneId zone ZoneId.systemDefault();DateTimeFormatter df DateTimeFormatter.ofPattern(yyyy-MM-dd HH:mm:ss);LocalDateTime birthDate LocalDateTime.parse(2022-03-11 00:00:00, df);Instant instant birthDate.atZone(zone).toInstant();Date date Date.from(instant);System.out.println(birthDate: birthDate);System.out.println(instant: instant);System.out.println(date: date);}支持 $filter 数组聚合运算符
Java Spring Data MongoDB是用于与MongoDB数据库进行交互的框架提供了许多功能强大的 API 和管理工具其中包含了大量数据操作函数包括数组聚合运算符$filter也是其中一种。
在MongoDB中当需要使用聚合函数过滤数组中的元素时可以使用$filter运算符。具体使用方法如下
{
$project: {
filteredArray: {
$filter: {
input: $array,
as: element,
cond: { $gt: [$$element, 5] }
}
}
}
}上述代码将会筛选数组中所有大于5的元素并返回一个新的数组。
在Java Spring Data MongoDB中$filter运算符同样被支持。可以使用AggregationOperation来拼接查询条件。具体实现代码如下
AggregationOperation filter Aggregation.project()
.andFilter(ArrayOperators.Filter
.filter(array)
.as(element)
.by(ComparisonOperators.Gt.valueOf($$element).greaterThan(5)))
.as(filteredArray);在上述代码中使用了ArrayOperators.Filter来表示$filter运算符并使用ComparisonOperators.Gt来表示’符号从而实现了对数组中元素进行筛选。
需要注意的是 f i l t e r 操作符只适用于聚合操作中即使用聚合函数进行筛选。如果想要在数据操作中对数组中的元素进行筛选则需要使用 filter操作符只适用于聚合操作中即使用聚合函数进行筛选。如果想要在数据操作中对数组中的元素进行筛选则需要使用 filter操作符只适用于聚合操作中即使用聚合函数进行筛选。如果想要在数据操作中对数组中的元素进行筛选则需要使用elemMatch操作符来实现。具体操作方法可参考以下代码
Criteria criteria Criteria.where(array).elemMatch(
Criteria.where($gt).gt(5));
Query query new Query(criteria);
ListDBObject results mongoTemplate.find(query, DBObject.class,collectionName);上述代码使用$elemMatch操作符来筛选数组中所有大于5的元素并使用mongoTemplate.find方法来获取符合条件的数据项。
扩展的相关知识点也非常广泛如MongoDB聚合函数的使用、Java Spring Data MongoDB的API使用、MongoDB数据库的操作等。在实际应用过程中需要注意的是在使用聚合函数进行操作时应尽量避免数据过多而导致的性能可以采用分批次操作的方法来进行优化。同时需要根据实际情况来选择 e l e m M a t c h 或者 elemMatch或者 elemMatch或者filter操作符以及其他更合适的操作函数来实现查询需求。
参考
1、菜鸟教程 - mongodb
2、超级小豆丁 - MongoDB 介绍
3、MongoDB 文档查询 api 介绍