gpt4 book ai didi

regex - 是否有允许在 Mongodb 聚合管道中使用正则表达式的解决方法

转载 作者:可可西里 更新时间:2023-11-01 09:59:19 24 4
gpt4 key购买 nike

我正在尝试创建一个管道来计算有多少文档符合某些条件。不过,我看不到在条件中使用正则表达式的任何方法。这是带有注释的我的管道的简化版本:

db.Collection.aggregate([
// Pipeline before the issue
{'$group': {
'_id': {
'field': '$my_field', // Included for completeness
},
'first_count': {'$sum': { // We're going to count the number
'$cond': [ // of documents that have 'foo' in
{'$eq: ['$field_foo', 'foo']}, 1, 0 // $field_foo.
]
}},

'second_count': {'$sum': { // Here, I want to count the
'$cond': [ // Number of documents where
{'$regex': ['$field_bar', regex]}, 1, 0 // the value of 'bar' matches
] // the regex
}},
},
// Additional operations
])

我知道语法有误,但我希望这能传达我正在尝试做的事情。有没有办法在 $cond 操作中执行此匹配?或者,我也愿意接受在管道中较早的某个地方进行匹配并将结果存储在文档中的可能性,这样我此时只需匹配一个 bool 值。

最佳答案

这个问题好像来了很多次都无解。我知道有两种可能的解决方案:解决方案 1- 使用 mapReduce。 mapReduce 是聚合的一般形式,让用户可以做任何可以想象和可编程的事情。

以下是使用 mapReduce 的 mongo shell 解决方案我们考虑以下“st”集合。

db.st.find()

{ "_id" : ObjectId("51d6d23b945770d6de5883f1"), "foo" : "foo1", "bar" : "bar1" }
{ "_id" : ObjectId("51d6d249945770d6de5883f2"), "foo" : "foo2", "bar" : "bar2" }
{ "_id" : ObjectId("51d6d25d945770d6de5883f3"), "foo" : "foo2", "bar" : "bar22" }
{ "_id" : ObjectId("51d6d28b945770d6de5883f4"), "foo" : "foo2", "bar" : "bar3" }
{ "_id" : ObjectId("51d6daf6945770d6de5883f5"), "foo" : "foo3", "bar" : "bar3" }
{ "_id" : ObjectId("51d6db03945770d6de5883f6"), "foo" : "foo4", "bar" : "bar24" }

我们想按 foo 分组,并且对于每个 foo,计算 doc 的数量,以及带有包含子字符串 'bar2' 的 bar 的 doc 的数量。即:

foo1: nbdoc=1, n_match = 0
foo2: nbdoc=3, n_match = 2
foo3: nbdoc=1, n_match = 0
foo4: nbdoc=1, n_match = 1

为此,定义以下映射函数

var mapFunction = function() {
var key = this.foo;
var nb_match_bar2 = 0;
if( this.bar.match(/bar2/g) ){
nb_match_bar2 = 1;
}
var value = {
count: 1,
nb_match: nb_match_bar2
};

emit( key, value );
};

和下面的reduce函数

var reduceFunction = function(key, values) {

var reducedObject = {
count: 0,
nb_match:0
};
values.forEach( function(value) {
reducedObject.count += value.count;
reducedObject.nb_match += value.nb_match;
}
);
return reducedObject;
};

运行 mapduce 并将结果存储在集合 map_reduce_result 中

db.st.mapReduce(mapFunction, reduceFunction, {out:'map_reduce_result'})
{
"result" : "map_reduce_result",
"timeMillis" : 7,
"counts" : {
"input" : 6,
"emit" : 6,
"reduce" : 1,
"output" : 4
},
"ok" : 1,
}

最后,我们可以查询集合 map_reduce_result,瞧!解决方案

> db.map_reduce_result.find()
{ "_id" : "foo1", "value" : { "count" : 1, "nb_match" : 0 } }
{ "_id" : "foo2", "value" : { "count" : 3, "nb_match" : 2 } }
{ "_id" : "foo3", "value" : { "count" : 1, "nb_match" : 0 } }
{ "_id" : "foo4", "value" : { "count" : 1, "nb_match" : 1 } }

解决方案 2- 使用两个单独的聚合和合并我不会提供此解决方案的详细信息,因为任何 mongo 用户都可以轻松做到。第 1 步:进行聚合,忽略需要正则表达式求和的部分。第 2 步:对与第一步相同的键进行第二次聚合分组。 管道的第一阶段:匹配正则表达式; 阶段 2:在与第一步相同的键上进行分组,并计算每组中文档的数量 {$sum: 1};第 3 步:合并第 1 步和第 2 步的结果:为出现在两个结果中的每个键添加新字段,如果该键不存在于第二个结果中,则将新键设置为 0。

瞧!另一种解决方案。

关于regex - 是否有允许在 Mongodb 聚合管道中使用正则表达式的解决方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17458190/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com