criteria mysql filed_mongo根据字段值进行排序,类似mysql的field函数功能

背景:现有一个字段state,字段值为1,2,3,4;现在列表页需要根据字段值进行排序,要求值为2的排在前面,其他状态的数据根据修改时间倒序展示,如果是mysql数据库可以直接使用field函数进行排序,但是现在使用的数据库为mongo,没有类似函数的支持,所以采用类似case when的方式实现该功能,主要代码如下:

import org.springframework.data.domain.Page;

import org.springframework.data.domain.PageImpl;

import org.springframework.data.domain.PageRequest;

import org.springframework.data.domain.Pageable;

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.ConditionalOperators;

import org.springframework.data.mongodb.core.aggregation.Fields;

import org.springframework.data.mongodb.core.query.Criteria;

import org.springframework.data.mongodb.core.query.Query;

import javax.annotation.Resource;

@Repository

public class UserDaoImpl implements UserDao {

@Resource

private MongoTemplate mongoTemplate;

public Page getPage(Object param) {

// 根据参数拼接查询条件,getQueryCriteria为内部方法,具体实现忽略

Criteria criteria = getQueryCriteria(param);

Query query = Query.query(criteria);

// 使用MongoTemplate查询总数

long total = mongoTemplate.count(query, UserPO.class);

int pageNo = 1;

int pageSize = 10;

Pageable pageable = PageRequest.of(pageNo - 1, pageSize);

// 生成冗余结果字段,如果字段值为2,赋值为1,其他值赋值为0

ConditionalOperators.Cond condOperation = ConditionalOperators.when(Criteria.where("state").is(2))

.thenValueOf("1")

.otherwise("0");

// 计算skip值

long skip = (pageNo - 1) * pageSize;

// 获取所有字段,getBaseFields为内部方法,具体实现忽略

Fields fields = getBaseFields();

Aggregation aggregation = Aggregation.newAggregation(

// 将上面的state字段命名为sortNo

Aggregation.project(fields).and(condOperation).as("sortNo"),

Aggregation.match(criteria),

// 先根据state倒序排序,再根据修改时间倒序排序,即可实现根据state的值进行排序,类似mysql field函数排序的功能

Aggregation.sort(Sort.by(Sort.Order.desc("sortNo"), Sort.Order.desc("modifiedAt"))),

Aggregation.skip(skip), Aggregation.limit(pageSize));

AggregationResults resultList =

mongoTemplate.aggregate(aggregation, UserPO.class, UserPO.class);

return new PageImpl<>(resultList.getMappedResults(), pageable, total);

}

}

目前还没有其他更好的方法,如果有其他方式实现,请在评论中提出。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
可能是因为您使用了 `sortBy` 方法,但未提供正确的排序字段排序顺序。请确保指定正确的排序字段排序方向。 另外,也可能是因为您的查询结果中存在重复的记录,导致排序结果不一致。您可以尝试使用 `distinct()` 方法去除重复记录,然后再进行排序。 以下是一个示例代码,演示了如何使用 mongoTemplate 进行联合查询和排序: ```java Criteria criteria1 = Criteria.where("field1").is("value1"); // 表1查询条件 Criteria criteria2 = Criteria.where("field2").is("value2"); // 表2查询条件 AggregationOperation match1 = Aggregation.match(criteria1); // 表1查询操作 AggregationOperation match2 = Aggregation.match(criteria2); // 表2查询操作 AggregationOperation lookup = Aggregation.lookup("table2", "table1Field", "table2Field", "table2"); // 联合查询操作 AggregationOperation unwind = Aggregation.unwind("table2"); // 解开查询结果中嵌套的数组 AggregationOperation sort = Aggregation.sort(Sort.Direction.DESC, "table2.fieldToSort"); // 根据表2的排序字段进行排序 AggregationOperation project = Aggregation.project("table1Field", "table2.fieldToSort"); // 投影查询结果,只返回需要的字段 Aggregation aggregation = Aggregation.newAggregation(match1, match2, lookup, unwind, sort, project); // 构建查询聚合操作 AggregationResults<YourResultClass> results = mongoTemplate.aggregate(aggregation, "table1", YourResultClass.class); // 执行查询,并将结果映射到 YourResultClass 类型 ``` 注:以上示例中没有去重操作,如果您的查询结果存在重复记录,可以在 sort 操作之前添加如下去重操作: ```java AggregationOperation group = Aggregation.group("table2._id").first("$$ROOT").as("root"); // 按照表2的主键(或其他唯一字段)进行分组,返回每组第一个记录 AggregationOperation replaceRoot = Aggregation.replaceRoot("root"); // 重新设置根节点,即返回经过去重后的查询结果 Aggregation aggregation = Aggregation.newAggregation(match1, match2, lookup, unwind, group, replaceRoot, sort, project); // 增加去重操作 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值