将自动排名维护为MongoDB中的列

时间:2017-01-18 10:46:14

标签: sql mongodb database

我使用MongoDB作为我的数据库。

我的数据包含排名和列名。现在,可以使用与已存在的等级不同的等级更新新行,或者可以使用相同的行。

如果相同则必须调整其他行的等级。

排名小于要插入的排的行必须加1,并且具有排名的行可以保持不变。

功能类似于MS Word类型的应用程序中的数字项目符号列表。在两者之间插入一行时,调整其下面其他行的编号。

等级1是最高等级。

例如有3行

Name  Rank
A       1
B       2
C       3

现在我想更新一行,其中D为名称,2为排名。所以现在在插入行之后,DB应该在下面

Name  Rank
A       1
B       3
C       4
D       2 

可能使用数据库触发器我可以通过更新其他行来实现此目的。

我有几个问题

(a)除了使用数据库触发器实现这种情况之外还有其他更好的方法吗?更新所有行可能是一项耗时的工作。

(b)MongoDB本身是否支持数据库触发器?

最诚挚的问候,

Saurav

1 个答案:

答案 0 :(得分:1)

不,MongoDB,还没有提供触发器。此外,我不认为触发器是实现这一目标的好方法。

所以我想提出一些想法,看看是否有意义。

方法1

也许不是扰乱那么多文档,你可以创建一个只有一个文档的集合(让我们调用集合排名)。在该文档中,有一个数组字段调用队列。由于它是一个数组,它已经维持了一个序列。

{
 _id : "RANK",
 "ranks" : ["A","B","C"]
}

现在,如果你想在第二个位置将D添加到此等级

db.ranking.update({_id:"RANK"},{$push : {"ranks":{$each : ["D"],$position:1}}});

它会将D添加到索引1,这是第二个位置,考虑到索引从0开始。

{
 _id : "RANK",
 "ranks" : ["A","D","B","C"]
}

但是有一个问题,如果你想将C位置从第4位改为第1位,你需要将其从末端移除并将其放在开头,我相信这两项操作都无法在单一中完成更新(没有多挖掘选项),所以我们可以运行两个查询

db.ranking.update({_id:"RANK"},{$pull : {"ranks": "C"}});
db.ranking.update({_id:"RANK"},{$push : {"ranks":{$each : ["C"],$position:0}}});

然后就好了 {  _id:" RANK",  "排" :[" C"," A"," D"," B"] }

保持序列的其余部分。

现在你可能想要存储id而不是A,B,C等。一个文件可以是16MB所以基本上这个数组可以存储超过130万个id的条目,如果id是每个12字节的MongoDB ObjectId。如果这还不够,我们仍然可以选择进一步排名的后续文件。

方法2

你也可以,而不是排名为数字,只需要有两个字段,如followBy和precededBy。

所以您的用户文档看起来

{
 _id:"A"
 "followedBy":"B",
}
{
 _id:"B"
 "followedBy":"C",
 "precededBy":"A"
}
{
 _id:"c"
 "precededBy":"B",
}

如果你想在第二个位置添加D,那么你需要改变当前的第二个位置,你需要插入新的一个,所以它只会改变两个文件

{
 _id:"A"
 "followedBy":"B",
}
{
 _id:"B"
 "followedBy":"C",
 "precededBy":"D" //changed from A to D
}
{
 _id:"c"
 "precededBy":"B",
}
{
 _id:"D"
 "followedBy":"B",
 "precededBy":"A"
}

这种方法的缺点是,除非您在应用程序中获得所有这些并创建链接列表结构,否则您无法根据排名对查询进行排序。

这种方法只保留最低DB更改的排名。