更新数组子项排序顺序 [英] Update Array Children Sorted Order

查看:69
本文介绍了更新数组子项排序顺序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个包含具有以下结构的对象的集合

I have a collection containing objects with the following structure

{
"dep_id": "some_id",
"departament": "dep name",
"employees": [{
   "name": "emp1",
   "age": 31
  },{
   "name": "emp2",
   "age": 35
  }]
}

我想按employees.age降序对id为"some_id"的对象的雇员数组进行排序和保存.最好的结果是使用mongodb的查询语言自动完成此操作.这可能吗?

I would like to sort and save the array of employees for the object with id "some_id", by employees.age, descending. The best outcome would be to do this atomically using mongodb's query language. Is this possible?

如果没有,如何在不影响父级其他数据或子文档数据的情况下重新排列子文档?如果我必须从数据库中下载数据并保存排序后的子级数组,那么如果其他操作对其中一个子级执行更新,或者同时添加或删除了子级,会发生什么呢?

If not, how can I rearrange the subdocuments without affecting the parent's other data or the data of the subdocuments? In case I have to download the data from the database and save back the sorted array of children, what would happen if something else performs an update to one of the children or children are added or removed in the meantime?

最后,应将数据持久保存到数据库中,如下所示:

In the end, the data should be persisted to the database like this:

{
"dep_id": "some_id",
"departament": "dep name",
"employees": [{
   "name": "emp2",
   "age": 35
  },{
   "name": "emp1",
   "age": 31
  }]
}

推荐答案

做到这一点的最佳方法是实际应用我的实际对象有一个等级"和"created_at"" ,这意味着您确实应该在问题中问这个问题,而不是写一个人为"案例(不知道为什么人们会这样做).

The best way to do this is to actually apply the $sort modifier as you add items to the array. As you say in your comment "My actual objects have a "rank" and 'created_at'", which means that you really should have asked that in your question instead of writing a "contrived" case ( don't know why people do that ).

因此,要对多个属性进行排序",以下参考将进行如下调整:

So for "sorting" by multiple properties, the following reference would adjust like this:

db.collection.update(
  {  },
  { "$push": { "employees": { "$each": [], "$sort": { "rank": -1, "created_at": -1 } } } },
  { "multi": true }
)

但是要更新您当前拥有的所有数据(如问题中所示),则可以在"age"上进行排序:

But to update all the data you presently have "as is shown in the question", then you would sort on "age" with:

db.collection.update(
  {  },
  { "$push": { "employees": { "$each": [], "$sort": { "age": -1 } } } },
  { "multi": true }
)

奇怪地使用 $push 来实际修改"数组?是的,这是真的,因为 $each 修饰符表示我们实际上没有添加任何新内容,但 $sort 修饰符实际上是将要应用于数组并对其进行重新排序".

Which oddly uses $push to actually "modify" an array? Yes it's true, since the $each modifier says we are not actually adding anything new yet the $sort modifier is actually going to apply to the array in place and "re-order" it.

当然,这将随后说明如何应用阵列的新"更新才能应用该

Of course this would then explain how "new" updates to the array should be written in order to apply that $sort and ensure that the "largest age" is always "first" in the array:

db.collection.update(
  { "dep_id": "some_id" },
  { "$push": { 
    "employees": { 
      "$each": [{ "name": "emp": 3, "age": 32 }],
      "$sort": { "age": -1 } 
    }
  }}
)

因此,当您在更新时将新条目添加到阵列时,会发生以下情况: $sort 修饰符,并将新元素重新定位在两个现有元素之间,因为这是该元素的排序位置.

So what happens here is as you add the new entry to the array on update, the $sort modifier is applied and re-positions the new element between the two existing ones since that is where it would sort to.

这是MongoDB的常见模式,通常与 $slice 修饰符,以便在添加新项目时使数组保持最大"长度,但保留有序"结果.通常,排名"是确切的用法.

This is a common pattern with MongoDB and is typically used in combination with the $slice modifier in order to keep arrays at a "maximum" length as new items are added, yet retain "ordered" results. And quite often "ranking" is the exact usage.

因此,总的来说,您实际上可以更新"现有数据,并使用一个简单的原子语句"对其进行重新排序.无需循环或集合重命名.此外,您现在有了一个简单的原子方法来更新"数据并在添加或删除新数组项时保持该顺序.

So overall, you can actually "update" your existing data and re-order it with "one simple atomic statement". No looping or collection renaming required. Furthermore, you now have a simple atomic method to "update" the data and maintain that order as you add new array items, or remove them.

这篇关于更新数组子项排序顺序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆