更改元素排序索引的有效方法

时间:2012-09-25 20:41:03

标签: java algorithm google-app-engine data-structures google-cloud-datastore

我的非sql数据库中有一个非常大的元素列表。

每个元素都有一个从1到N的排序顺序。此排序顺序指定结果在表单上的显示方式。

当在UI中触发更改顺序(将元素i放在位置j)时,我需要更新之间的所有实体。如果元素1变得最新,我需要进行N次更新。

是否有一种有效的方法可以降低这项操作的成本?有没有一种智能的方法来索引排序值?

一些注意事项:

  • 我正在重新设计我的应用程序,因此我可以用更智能的解决方案重新索引实体。
  • 写入(更新)的成本比获取(读取1实体)大+ -4倍。
  • 列表很大,不适合记忆。

4 个答案:

答案 0 :(得分:2)

  1. 重新索引您的实体。将order属性设置为double。
  2. 每次用户将实体移动到新位置时,请在其他两个实体之间为其分配新的订单属性:

    entityA.setOrder((entityB.getOrder()+ entityC.getOrder())/ 2);

  3. 保存实体A(属性“订单”应编入索引)。

  4. 当用户请求10000到10200之间的实体时,请使用排序顺序在您的订单属性上构建查询。检索10000到10200之间的结果:

    datastore.prepare(Q).asList(FetchOptions.Builder.withOffset(10000).limit(200));

  5. 永远不要再重新索引您的实体。每次保存实体时,数据存储区都会为您执行此操作。

答案 1 :(得分:1)

我假设您将实体存储在GAE数据存储区中,并让数据存储区为您索引实体。数据存储区使用类似索引的链接列表,但您无权访问链接列表。

我认为没有一个完美的机制,但是我不是从1..N中对N个项目进行排序,而是使用大量稀疏数字(例如,使用浮点数),并将您的实体均匀分布那个范围。无论何时对项目进行排序,只需生成两个新邻居之间存在的新索引值。

如果遇到最糟糕的情况,邻居太靠近,为邻居生成新索引,等等。更高级的系统可以保证每次重新排序后实体之间的空间最小,并主动重新索引一些额外的邻居。

答案 2 :(得分:-1)

在我看来,目前的型号没有其他选择。像索引集合一样,移动它们时必须“重新索引”元素:减少或增加集合的一部分

更改模型可以满足您的要求。您可以尝试将其设计为链表,其中删除/移动/插入操作“更便宜”。每个元素都知道它的下一个(简单)或下一个和前一个元素(Double)

答案 3 :(得分:-2)

你可以分开排序顺序&来自每个实体中其他庞大数据的UI数据。后者可以保持不变。

嗯,如果你有这个:

entitles = [bigdata1, bigdata2, bigdata3, ...]
order_numbers = [2, 3, 1, ...]

order_numbers可以是排序或任意用户定义值的结果。

然后你有

display_order = [2, 0, 1, ...]

表示首先显示bigdata3。如果UI想要以任何方式更改订单,则只有order_numbers和display_order需要更改,而不是权限。这是我的理解。