Sql 在MongoDB中将自动排名作为一列进行维护

Sql 在MongoDB中将自动排名作为一列进行维护,sql,mongodb,database,Sql,Mongodb,Database,我使用MongoDB作为我的数据库 我有数据,其中包含排名和名称列。现在,可以使用不同于现有列组或相同列组的列组更新新行 如果相同,则必须调整其他行的秩 秩小于要插入的行的行必须增加1,并且具有秩的行可以保持原样 该功能类似于MS Word应用程序类型中的数字项目符号列表。如果在两行之间插入一行,请调整其下方其他行的编号 排名1是最高的排名 例如,共有3行 Name Rank A 1 B 2 C 3 现在我想更新一行,其中D作为名称,2作为秩。现在在插入行

我使用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 
可能通过使用数据库触发器,我可以通过更新其他行来实现这一点

我有几个问题

有没有比使用数据库触发器更好的方法来实现这种场景?更新所有行可能是一项耗时的工作

MongoDB是否本机支持数据库触发器

致以最良好的祝愿


Saurav不,MongoDB还没有提供触发器。我也不认为触发器是实现这一点的好方法

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

方法1

也许你可以创建一个只包含一个文档的集合,我们称之为集合排名,而不是干扰那些文档。在该文档中,有一个数组字段调用。因为它是一个数组,所以它已经在维护一个序列

{
 _id : "RANK",
 "ranks" : ["A","B","C"]
}
现在如果你想在这个排名第二的位置加上D

db.ranking.update({_id:"RANK"},{$push : {"ranks":{$each : ["D"],$position:1}}});
考虑到指数从0开始,它会将D添加到第二位的指数1中

{
 _id : "RANK",
 "ranks" : ["A","D","B","C"]
}
但是有一个问题,如果你想把C的位置从第四位改为第一位,你需要把它从末尾去掉,放在开头,我确信这两个操作不能在一次更新中实现,因为没有深入挖掘选项,所以我们可以运行两个查询

db.ranking.update({_id:"RANK"},{$pull : {"ranks": "C"}});
db.ranking.update({_id:"RANK"},{$push : {"ranks":{$each : ["C"],$position:0}}});
那就好像 { _id:等级, 职级:[C、A、D、B] }

保持序列的其余部分

{
 _id : "RANK",
 "ranks" : ["A","B","C"]
}
现在,您可能希望存储id,而不是A、B、C等。一个文档可以是16MB,因此基本上,如果id是每个12字节的MongoDB ObjectId,那么这个列组数组可以存储130多万个id条目。如果这还不够,我们仍然可以选择进一步排名的后续文件

方法2

您还可以使用followedBy和preferencedby这两个字段,而不是将秩作为数字

因此,您的用户文档看起来

{
 _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"
}
这种方法的缺点是,除非您在应用程序中获得所有这些内容并创建linkedlist类型的结构,否则无法根据排名在查询中排序


这种方法只需将数据库更改降至最低即可保留排名。

非常感谢Rahul的回答…我计划使用选项1…数据多于名称…因此必须使用单个文档集合和主集合执行展开查找方法1也是我的选择,维护一个文档数组是可以的,但是我会避免放置更多的嵌套数组,因为执行操作会很困难。同时,我还建议将一些字段作为文档放在ranks数组中,而不是尽可能通过查找运行聚合。不仅查找成本高,聚合本身在术语或内存方面也有限制。嗨,Rahul…感谢您的持续帮助…我想您的意思是在rank集合中创建一个文档数组?…所以…因为我可以在单个文档中的数组中创建数百万个文档。。这是一个很好的数据库优化吗?不仅很好,在我看来,这是首选的方法,单个文档中的操作是原子的,所以您可以使用更新调用覆盖事务。数组中的文档很好,我不会放大的文档,比如说3-4个必填字段。您还可以在数组字段上使用多键索引来进一步优化它。