MongoDB将sql转换为mongo查询(使用id-1连接)
我想更改以下sql查询:MongoDB将sql转换为mongo查询(使用id-1连接),mongodb,Mongodb,我想更改以下sql查询: select a1.opis_ruchu as poprzednik, a2.opis_ruchu as nastepnik, count(a1.opis_ruchu) as ilosc_wystapien from public.informacje a1 join public.informacje a2 on a1.id = a2.id-1 group by a1.opis_ruchu, a2.opis_ruchu; 到蒙哥 目前我有: db.informacj
select a1.opis_ruchu as poprzednik, a2.opis_ruchu as nastepnik,
count(a1.opis_ruchu) as ilosc_wystapien
from public.informacje a1 join public.informacje a2
on a1.id = a2.id-1
group by a1.opis_ruchu, a2.opis_ruchu;
到蒙哥
目前我有:
db.informacje.aggregate(
[
{
"$project" : {
"_id" : NumberInt(0),
"a1" : "$$ROOT"
}
},
{
"$lookup" : {
"localField" : "id",
"from" : "informacje",
"foreignField" : "id-1",
"as" : "a2"
}
}
,
{
"$group" : {
"_id" : {
"poprzednik" : "$a1.opis_ruchu",
"nastepnik" : "$a2.opis_ruchu"
},
"COUNT(a1᎐opis_ruchu)" : {
"$sum" : NumberInt(1)
}
}
}
])
问题是:当nastepnik多个一时,poprzednik字段只存在一次
例如,在SQL中,我有:
poprzednik nastepnik ilosc_wystapien
左左500
在Mongo有:
poprzednik nastepnik
左“左”、“左”、“左”
收集示例:
> db.informacje.find().pretty()
{
"_id" : ObjectId("5fa7f372fdd610505c57d5d6"),
"id" : 1,
"opis_ruchu" : "left"
}
{
"_id" : ObjectId("5fa7f372fdd610505c57d5d7"),
"id" : 2,
"opis_ruchu" : "left"
}
{
"_id" : ObjectId("5fa7f372fdd610505c57d5d8"),
"id" : 3,
"opis_ruchu" : "left"
}
{
"_id" : ObjectId("5fa7f372fdd610505c57d5d9"),
"id" : 4,
"opis_ruchu" : "left"
}
从id=501开始,我有“opis_ruchu”:“right”项目只应在最后一个阶段使用一次-它不会更改处理的信息,只更改显示的内容
db.informacje.aggregate(
[
{
"$lookup" : {
"localField" : "id",
"from" : "informacje",
"foreignField" : "id-1",
"as" : "a2"
}
}
,
{
"$group" : {
"_id" : {
"poprzednik" : "$a1.opis_ruchu",
"nastepnik" : "$a2.opis_ruchu"
},
"COUNT(a1᎐opis_ruchu)" : {
"$sum" : NumberInt(1)
}
}
},
{
"$project" : { poprzednik: 1, nastepnik: 1,
"sum" : "COUNT(a1᎐opis_ruchu)",
}
},
])
这看起来很复杂,要想得到你想要的东西,我发现把SQL“翻译”成我想做的事情,然后把它“翻译”成mongo是很有帮助的。
在SQL中,您根据记录自己的opis_ruchu值加上上上一条记录的opis_ruchu值对记录进行分组,并显示这些组加上计数
如果您有500个ID不断增加的条目,“左”为opis_ruchu,然后ID501-1000为“右”,那么您的SQL的结果应该是:
left left 499 (because id 1 has no match, there's no id 0)
right left 1 (this is id 501 compared to id 500)
right right 499 (this is for id's 502-1000)
不过,要得到两大块ID的结果似乎需要做很多工作。如果你能用你的应用程序所做的来解释的话,Mongo中可能有一种更有效的方法来做你想做的事情。@Sheeri谢谢你的帮助。运行脚本后,请保存以下数据:
{ "_id" : { "poprzednik" : "right", "nastepnik" : [ ] }, "sum" : "COUNT(opis_ruchu)" }
{ "_id" : { "poprzednik" : "left", "nastepnik" : [ ] }, "sum" : "COUNT(opis_ruchu)" }
我认为主要的问题是字段id-1。更好的方法是使用$group,然后使用$match,如下例所示:
最后还是只有$project。我喜欢做的一件事是使用MongoDB compass——这是一个免费的GUI工具,但您可以可视化管道的每个阶段。例如: 在第一阶段($lookup)之后,您可以看到a2是一个空数组。你是对的,这是因为“id-1”。使用$lookup时,您不能操作字段,但可以在$lookup之前使用$addFields: 因此,您可以看到查找已成功-id=1在a2中没有任何内容,因为没有id=0,但id=2在a2中有一个数组,它是id=1的完整记录 (使用Compass和聚合管道,您可以在运行过程中看到各个阶段,这使调试更加容易) 从这里开始,您希望a2不是一个数组(您无法避免,因为查找总是导致一个数组)。因此,您将获取数组中的值并为数组中的每个项目创建文档…然后执行以下操作: 正如您从小组中看到的,您不需要任何投影,因为您的数据已经是您想要的格式 因此,管道是:
db.informacje.aggregate[{$addFields: {
prevId: {$subtract: ["$id",1]}
}}, {$lookup: {
localField: 'prevId',
from: 'informacje',
foreignField: 'id',
as: 'a2'
}}, {$unwind: {
path: '$a2',
preserveNullAndEmptyArrays: true
}}, {$group: {
_id: {
poprzednik: '$opis_ruchu',
nastepnik: '$a2.opis_ruchu'
},
'sum': {
$sum: 1
}
}}]
您能提供一个示例集合吗?@J.F.我还添加了示例集合谢谢您的帮助。运行脚本后,我有以下数据:{“\u id”:{“poprzednik”:“right”,“nastepnik”:[]},“sum”:“COUNT(opis\u ruchu)”}{“\u id”:{“poprzednik”:“left”,“nastepnik”:[]},“sum”:“COUNT(opis\u ruchu)”},我也将其添加为答案哦,这一行:
sum”:“COUNT(a1᎐opis_ruchu)“
,可能必须是。sum”:计数(a1᎐opis_ruchu)
,去掉计数字段周围的引号。老实说,我会将该字段的名称更改为countA1,因为它更易于阅读和调试(您必须在$group和$project阶段中更改它)。我喜欢做的一件事是使用MongoDB compass—这是一个免费的GUI工具,但您可以可视化管道的每个阶段。好的,非常感谢。我会尽量这样做:)