当前位置:   article > 正文

Mongodb——使用Mongodb对字段中字符串内容进行截取,并进行分组统计_mongotemplate 截取字段

mongotemplate 截取字段


)

转自:https://codeleading.com/article/90243876662/

针对字段中某部分内容的指标统计

在使用mongodb进行指标统计的时候可能遇见下面的数据结构。

/* 1 */
{
    "_id" : ObjectId("5edf4b5c64574814bc8ae4ae"),
    "address" : "河南,信阳",
    "state" : 0,
    "remark" : "发送成功",
    "createAt" : NumberLong(1591199999000)
}

/* 2 */
{
    "_id" : ObjectId("5edf4ca064574814bc8ae4d5"),
    "address" : "湖北,武汉",
    "state" : 0,
    "remark" : "发送成功",
    "createAt" : NumberLong(1591199999000)
}

/* 3 */
{
    "_id" : ObjectId("5edf4cac64574814bc8ae4d9"),
    "address" : "湖北,宜昌",
    "state" : 0,
    "remark" : "发送成功",
    "createAt" : NumberLong(1591199999000)
}


  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

在某些时候我们可能需要根据地区信息来统计一些数据,但是数据并非是绝对干净的,可能只需要我们根据部分字段进行统计。

这个时候就需要使用 s p l i t 或者使用 split或者使用 split或者使用substr进行分组计算。

比如上面的数据中需要我们统计每个省下面业务数据内容。

使用split进行字符串截取

db.getCollection('AreaDemoLog').aggregate([
    {
        "$project": {
            // 首先使用$split对address字段进行切割,得到名称为regions的地区数组
            "regions": {
                "$split": ["$address",","]
            }
        }
    },
    {
        "$project": {
            "regions": 1,
            // 然后使用$arrayElemAt获得regions的地区数组中第一个元素,命名为 province 
            "province": {
                "$arrayElemAt": [ "$regions",0]
            }
        }
    },
    {
        "$group": {
            // 最后根据province字段分组求总
            "_id": "$province",
            "count": {
                "$sum": 1
            }
        }
    },
    {
        "$project": {
            "count": 1,
            "_id": 0,
            "province": "$_id"
        }
    }
])

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36

使用substr进行字符串截取

db.getCollection('AreaDemoLog').aggregate([
    {
        "$project": {
            // 首先使用$substrCP对address字段进行截取,然后直接得到目标字段
            "province": {
                $substrCP:  [ '$address', 0, 2 ]
            }
        }
    },
    {
        "$group": {
            // 最后根据province字段分组求总
            "_id": "$province",
            "count": {
                "$sum": 1
            }
        }
    },
    {
        "$project": {
            "count": 1,
            "_id": 0,
            "province": "$_id"
        }
    }
])

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

关于字符串截取注意

对于截取纯英文和数字的字符串结构的时候可以使用 s u b s t r 但是使用纯汉字的字段进行截取的时候,使用 substr但是使用纯汉字的字段进行截取的时候,使用 substr但是使用纯汉字的字段进行截取的时候,使用substr根据设置的编码情况会出现下面异常:

$substrBytes:  Invalid range, ending index is in the middle of a UTF-8 character.
  • 1

因为 s u b s t r 仅适用于 A S C I I 编码。所以这个时候需要使用 m o n g o d b 3.4 中引入的 substr仅适用于ASCII编码。所以这个时候需要使用mongodb 3.4中引入的 substr仅适用于ASCII编码。所以这个时候需要使用mongodb3.4中引入的substrCP来进行字符串切割。
上面两个查询都可以得到正确结果

/* 1 */
{
    "count" : 16.0,
    "province" : "湖北"
}

/* 2 */
{
    "count" : 1.0,
    "province" : "河南"
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

将上面查询转换为JAVA代码

    public static String test() {
        List<AggregationOperation> lstOperations = new ArrayList<>(10);
        // 切分地区
        AggregationOperation splitAgg =
            Aggregation.project().andExpression("{ $split: {'$address', ','}}").as("regions");
        lstOperations.add(splitAgg);

        ProjectionOperation province =
            Aggregation.project("$regions").andExpression("{ $arrayElemAt: { '$regions', 0 }}").as("province");
        lstOperations.add(province);
        // 求总
        AggregationOperation groupAgg = Aggregation.group("$province").count().as("count");
        lstOperations.add(groupAgg);
        // 定义查询内容
        ProjectionOperation projectionOperation =
            Aggregation.project("count").andExclude("_id").and("$_id").as("province");
        lstOperations.add(projectionOperation);

        AggregationOptions aggregationOptions = AggregationOptions.builder().allowDiskUse(true).build();
        //开始查询
        Aggregation agg = Aggregation.newAggregation(lstOperations).withOptions(aggregationOptions);
        AggregationResults<Map> groupResult = this.mongoTemplate.aggregate(agg, "AreaDemoLog", Map.class);
        return "";
    }


  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

使用substr进行字符串截取

    public static String test() {
        List<AggregationOperation> lstOperations = new ArrayList<>(10);
        // 切分地区
		ProjectionOperation province = 
			Aggregation.project().andExpression("{ $substrCP: { '$address', 0, 2 } }").as("province");
		lstOperations.add(province);
        // 求总
        AggregationOperation groupAgg = Aggregation.group("$province").count().as("count");
        lstOperations.add(groupAgg);
        // 定义查询内容
        ProjectionOperation projectionOperation =
            Aggregation.project("count").andExclude("_id").and("$_id").as("province");
        lstOperations.add(projectionOperation);

        AggregationOptions aggregationOptions = AggregationOptions.builder().allowDiskUse(true).build();
        //开始查询
        Aggregation agg = Aggregation.newAggregation(lstOperations).withOptions(aggregationOptions);
        AggregationResults<Map> groupResult = this.mongoTemplate.aggregate(agg, "AreaDemoLog", Map.class);
        return "";
    }


  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

将上面查询转换为JAVA代码需要注意内容

mongodb查询中我们使用了下面的语句

"$split": ["$address",","]

"$arrayElemAt": [ "$regions",0]

$substrCP:  [ '$address', 0, 2 ]

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

在使用MongodbTemplate进行查询的假如直接使用下面的拼写

andExpression("{ $split: [ '$address', ',' ] }")

andExpression("{ $arrayElemAt: [ '$regions', 0] }")

andExpression("{ $substrCP: [ '$address', 0, 2 ] }")


  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

最终的查询会出现下面异常

{
    "code": 1,
    "msg": "Expression [{ $split: ['$address', ',']}] @23: EL1043E: Unexpected token. Expected 'rsquare(])' but was 'comma(,)'"
}

  • 1
  • 2
  • 3
  • 4
  • 5

所以在将上面语句转到JAVA中的语句时候需要将"[…]“修改为”{…}"

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/286972
推荐阅读
相关标签
  

闽ICP备14008679号