我使用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
答案 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更改的排名。