在$ group聚合中使用$ regex $ reduce,以便显示长度

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在$ group聚合中使用$ regex $ reduce,以便显示长度相关的知识,希望对你有一定的参考价值。

我想我在这里有一个非常复杂的 - 不知道我能不能做到这一点。

我有包含地址和数据字段的数据。数据字段是十六进制值。我想运行一个聚合,按地址分组数据,然后是十六进制数据的长度。所有数据都将以16个字符长的形式出现,但该数据的长度应以字节为单位计算。

我想我必须取数据,去掉尾随的00(使用正则表达式00 + $),并将该数字除以2得到长度。之后,我将不得不按地址和最终字节长度进行分组。

示例数据集将是:

{addr:829, data:'4100004822000000'}
{addr:829, data:'4100004813000000'}
{addr:829, data:'4100004804000000'}
{addr:506, data:'0000108000000005'}
{addr:506, data:'0000108000000032'}
{addr:229, data:'0065005500000000'}

我想要的输出是:

{addr:829, length:5}
{addr:506, length:8}
{addr:229, length:4}

这甚至可以在聚合查询中使用,而不必使用外部代码吗?

答案

如果你的“数据”实际上是你在样本数据中显示的字符串,那么这并不复杂。假设数据存在并设置为某些内容(您可以根据需要添加错误检查),您可以获得所需的结果:

db.coll.aggregate([
    {$addFields:{lastNonZero:{$add:[2,{$reduce:{
        initialValue:-2,
        input:{$range:[0,{$strLenCP:"$data"},2]},
        in:{$cond:{
            if: {$eq:["00",{$substr:["$data","$$this",2]}]},
            then: "$$value",
            else: "$$this"
        }}
    }}]}}},
    {$group:{_id:{
        addr:"$addr", 
        length:{$divide:["$lastNonZero",2]}
    }}}
])

我使用了两个阶段,但当然如果你愿意,它们可以组合成一个$group。在$reduce,我一次通过data 2个字符,检查它们是否等于"00"。每次他们不是我更新值到我在序列中的位置。因为它返回最后一个非“00”字符的位置,所以我们向它添加2以查找到达结尾的零字符串开始的位置,然后在$ group中我们将其除以2以获得真实长度。

在您的示例数据上,返回:

{ "_id" : { "addr" : 229, "length" : 4 } }
{ "_id" : { "addr" : 506, "length" : 8 } }
{ "_id" : { "addr" : 829, "length" : 5 } }

您可以添加一个$project阶段,将字段名称转换为您想要返回的字段名称。

以上是关于在$ group聚合中使用$ regex $ reduce,以便显示长度的主要内容,如果未能解决你的问题,请参考以下文章

python常用模块之——正则re模块

正则表达式

如何在 Java 中获取 Group.Captures(来自 C# 中的 RegEx)的行为?

MongoDb 聚合在 $group 中使用 $sortByCount

正则表达式 for python

Python:简单REgex示例