【问题标题】:How to Sort an Array on Update如何在更新时对数组进行排序
【发布时间】:2015-02-12 23:05:03
【问题描述】:

例如我在 mongo 中的一篇博文:

{
  title: 'Some title',
  text: 'Text',
  tags: ['one', 'two', 'three']
}

有什么优雅的方法可以改变tags 的顺序吗? (任何语言或框架)

upd: 改变顺序是指以某种自定义方式改变元素顺序的能力 - 例如 ['two', 'one', 'three']

有一些明显的方法我认为并不完美:

  1. 如果我在每次编辑帖子时都标记copy and paste(从服务器到客户端并返回)——总有一天会发生竞争情况。

    例子:

    如果 Ann 开始在帖子上工作(并加载了 3 个标签以形成),那么 Bob 快速添加一个标签并保存帖子,Ann 将销毁他的编辑,因为她有一个旧数据。

  2. 我可以在服务器端检查列表的长度。但是用手来做这件事似乎很奇怪而且有问题——也许有人已经做过了?

  3. 我可以将嵌套列表放入特殊集合并使用整数order — 相关的数据库样式。

那么有什么问题呢?

  • 也许我错过了一些工具,该工具已经可以正确处理该排序。

  • 也许我只是不明白嵌套列表的实际用途(也许排序不是它们的优点)。

对于这个问题的任何帮助,我将不胜感激。

【问题讨论】:

  • 更改标签排序到底是什么意思?
  • 如果我正确地解决了您的问题,也许版本控制是您的解决方案:askasya.com/post/bestversion
  • @styvanesoukossi 例如,我有一个包含任务的待办事项列表,并希望以某种自定义方式对任务进行排序

标签: mongodb mongoose mongoid pymongo mongodb-query


【解决方案1】:

MongoDB 有自己的方法来对数组的值进行“排序”,您可以在不实际添加或删除修改时数组中存在的任何元素的情况下执行此操作。这意味着它是在服务器上自动执行的,无需通过网络读取文档然后将其发回。

考虑到您的示例文档,您可以这样做:

db.sample.update(
    {},
    { "$push": { "tags": { "$each": [], "$sort": 1 } } },
    { "multi": true}
)

这会产生:

{ 
    "title" : "Some title",
    "text" : "Text",
    "tags" : [ "one", "three", "two" ]
}

如果您想更具体地维护顺序,您可以随时将附加字段作为子文档添加到数组内容中:

{ 
    "title" : "Some title",
    "text" : "Text",
    "tags" : [ 
        { "name": "one", "pos": 1 },
        { "name": "three", "pos": 3 },
        { "name": "two", "pos": 2 }
    ]
}

然后应用类似的$sort操作:

db.sample.update(
    {}, 
    { "$push": { "tags": { "$each": [], "$sort": { "pos": 1 } } }},
    { "$multi": true }
)

有了这个结果:

{
    "title" : "Some title", 
    "text" : "Text", 
    "tags" : [ 
        { "name" : "one", "pos" : 1 },
        { "name" : "two", "pos" : 2 },
        { "name" : "three", "pos" : 3 }
    ] 
}

一开始有点晦涩,但与$each 修饰符一起,$sort 修饰符到$push 在更新时对数组的内容进行排序。因此,即使向数组添加“无”(如 $each 的空数组参数所表示的那样),排序也会应用于整个内容。

当然,在每次更新中移动数组内容是有代价的,即使添加实际值也可以,但当您“删除”项目时,它必须是一个单独的操作。 $pull 操作没有这样的当前参数。

您可能只想考虑在存储的文档中使用第二种形式,但如果这成为应用程序性能的问题,请执行实际的“排序”客户端。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-10-15
    • 2021-06-05
    • 1970-01-01
    • 1970-01-01
    • 2021-12-12
    • 1970-01-01
    • 2023-04-06
    • 1970-01-01
    相关资源
    最近更新 更多