mongo agrregate 学习笔记

推荐看官网 https://docs.spring.io/spring-data/data-mongodb/docs/current/reference/html/#mongo.aggregation


更新中。。。。。。

使用spring-data-mongodb的

mongoTemplate.aggregate(agg,"collectionName",OutputType.class)

mongoTemplate.aggregate(agg,InputType.class,OutputType.class)

时的注意事项

1.   

  *在使用mongoTemplate.aggregate(agg, "INPUT_COLLECTION_NAME", OutputType.class)时,

     * 第二个参数可以用collectionName或者使用与数据库中集合对应的实体类的class(InputType.class)
     * 如果使用collectionName 字符串,则拼接Operation时的字段需跟数据库collection中的字段名完全一样
     * 如果使用的是InputType.class(里面有document注解,标明了collectionname),则Operation拼接时的字段跟实体类里面的需一致
     * e.g:本方法中,如果用AccessEntity.class作为参数,则拼接criteria时不能使用channel_id,应该使用channelId字段
     * 如果使用AccessEntity.COLLECTION_NAME作为参数,则使用channel_id。原因是,在做解析的时候,
     * 如果用的collectionName 字符串,则对Option内的参数(例如channel_id)不做解析,
     * 如果用的InputType.class,则会解析Option内的参数,与InputType内的成员变量匹配,问题出在,解析时会将Option内的参数
     * 以下划线('_')分割字符串,就会造成解析失败,在源代码org.springframework.data.mapping.PropertyPath.class中

     * public static PropertyPath from(String source, TypeInformation<?> type)方法中做的(135行)

    *当然,返回的也是一样的,下面例子中,我返回了两个字段,分别是count,time_string。我指定了返回类型为StatisticsEntity.class,而实体中连个成员变量是count和timeString,如果要匹配,则需要加上@Feild注解,做别名转换,当然在用mongo的project命令操作是也可以指定别名,比如将Aggregation.project("_id","count").and("_id").as("time_string")改正Aggregation.project("_id","count").and("_id").as("timeString"),sort也要改,因为是按这个排序的。这样就可以不用@Feild注解了。

总之一句话就是为了将字段对应上。由于编程习惯,java代码喜欢(小)驼峰式命名,数据库喜欢下划线,所以就做好别名转换咯



参考代码,

public List<StatisticsEntiy> getDayPVStatistics(int channelId, int type, int begainTime, int endTime) {

        Criteria criteria = Criteria.where("channel_id").is(channelId).and("type").is(type).and("add_time").gte(begainTime).lte(endTime);
        MatchOperation match = Aggregation.match(criteria);
        GroupOperation group = Aggregation.group("add_date").count().as("count");
        ProjectionOperation project = Aggregation.project("_id","count").and("_id").as("time_string");
        SortOperation sort = Aggregation.sort(new Sort(Sort.Direction.DESC,"time_string"));
        Aggregation aggregate = Aggregation.newAggregation(match,group,project,sort);
        AggregationResults results = this.mongoAosTemplate.aggregate(aggregate,AccessEntity.COLLECTION_NAME,StatisticsEntiy.class);
        return results.getMappedResults();

    }
@Document(collection = "aos_channel_summary")
public class AccessEntity{

    public final static String COLLECTION_NAME = "aos_channel_summary";

    @Id
    private ObjectId id;

    @Field(value = "channel_id")
    private int channelId;

    @Field(value = "add_time_string")
    private String addTimeString;

    @Field(value = "add_time")
    private int addTime;

    @Field(value = "add_date")
    private String addDate;

    @Field(value = "add_month")
    private String addMonth;

    @Field(value = "ip")
    private String ip;

    @Field(value = "type")
    private int type;
    Setter/Getter方法省略
}
public class StatisticsEntiy  {

    @Field(value = "time_string")
    private String timeString;

    private int count;
}

2.group分组时(先看图)

有以下结构的mongo document




有两个命令,

命令1:

db.test.aggregate([
{$match:{type:{$eq:1}}},
{$group:{_id:{ip:"$ip",date:"$date"}}},
{$group:{_id:{date:"$_id.date"},count:{$sum:1}}},
{$sort:{"_id.date":1}},
{$project:{_id:0,date:"$_id.date",count:1}}
])

命令2:

db.test.aggregate([
{$match:{type:{$eq:1}}},
{$group:{_id:{ip:"$ip",date:"$date"}}},
{$group:{_id:"$_id.date",count:{$sum:1}}},
{$sort:{"_id":1}},
{$project:{_id:0,date:"$_id",count:1}}
])

输出结果都是下图



比较不同点

group分组都必须用_id作为主键,后面跟的是分组的字段,如果用{}包起来,里面是一个或多个键值对,如果只有一个分组字段可以用命令2(第四行)类似的 ,排序的时候,取值不加$符号

理解group中的{},比如本例子(命令第四行),如果加了{},则返回的结果的含义,无论分组字段是几个,都是如下格式,即_id是以集合的形式返回的,后面取值需要用_id.date


如果是分组单个字段不加{}时,则取值直接用_id就行了


到此,2结束了,这里主要就是用group命令时的一些小注意点,就跟特例似的,用{}键值对是最准确的语法,只是单个字段的时候,有第二种写法而已。


持续更新中。。。。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在MongoTemplate中进行排序,可以使用sort方法和Criteria对象。首先,您需要创建一个Criteria对象,用于指定排序的字段和顺序。然后,将该Criteria对象传递给sort方法,以指定排序的方式。 下面是一个示例代码,演示如何在MongoTemplate中进行排序: ```java import org.springframework.data.domain.Sort; import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.data.mongodb.core.query.Criteria; import org.springframework.data.mongodb.core.query.Query; @Autowired private MongoTemplate mongoTemplate; public List<Student> getSortedStudents() { // 创建一个Criteria对象,指定排序的字段和顺序 Criteria criteria = Criteria.where("age").gte(18).lte(25); // 例如按照age字段升序排序 // 创建一个Sort对象,定义排序方式 Sort sort = Sort.by(Sort.Direction.ASC, "age"); // 创建一个Query对象,将Criteria和Sort对象传递给它 Query query = new Query().addCriteria(criteria).with(sort); // 使用MongoTemplate的find方法执行查询并返回结果 List<Student> sortedStudents = mongoTemplate.find(query, Student.class); return sortedStudents; } ``` 在上述示例中,我们首先创建了一个Criteria对象,使用where方法指定了排序的字段和范围。然后,我们创建了一个Sort对象,定义了排序的方式。接下来,我们创建了一个Query对象,并通过addCriteria方法将Criteria对象添加到Query对象中,并通过with方法将Sort对象添加到Query对象中。最后,我们使用MongoTemplate的find方法执行查询,并将结果返回。 请注意,上述示例中的Student类是一个示例实体类,您需要根据您的实际情况自定义实体类和字段。 : https://example.com : https://example.com : https://example.com

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值