【问题标题】:ArangoDb get latest document from all collectionsArangoDb 从所有集合中获取最新文档
【发布时间】:2017-09-15 15:26:28
【问题描述】:

我开始认为我对数据的建模有点不正确,因为我无法查询它。

目前我拥有的是一堆客户(建模为每个客户的数据库) 这些客户有一堆设备:Device1...n(建模为每个设备的集合) 这些设备生成消息(建模为设备集合中的文档)。

为了给客户提供良好的反馈,我现在想支持检索客户的最新消息(每台设备一条消息)。

我很难找到描述如何查询多个集合的文档,因为一个客户可能有 1000 台设备,我宁愿不做 1000 台查询。

谢谢!

【问题讨论】:

  • 为什么客户需要了解数千台设备的最新消息?您不能根据客户的要求逐步交付每台设备的最新消息吗? (例如,动态加载和卸载数据的无限滚动,或简单的分页)

标签: arangodb aql nosql


【解决方案1】:

如果每个客户可以有 1000 台设备,并且设备消息存储在特定于设备的集合中,则为客户搜索最新消息将需要您在变量中找到 latest 记录集合的数量,这不仅难以在查询中表达,而且效率低下。

是否可以将给定客户的所有设备的消息放入单个客户特定集合中,并将设备 ID 作为属性存储在每个文档中?

例如:

// create customer-specific collections
db._create("messages_customer1");
db._create("messages_customer2");

// create an index on `dt` attribute in each collection 
// so messages can be queried efficiently sorted by date
db.messages_customer1.ensureIndex({ type: "skiplist", fields: [ "dt" ]});
db.messages_customer2.ensureIndex({ type: "skiplist", fields: [ "dt" ]});

// insert some messages for customer 1
db.messages_customer1.insert({ device: 123, dt: Date.now(), message: "foo" });
db.messages_customer1.insert({ device: 123, dt: Date.now(), message: "bar" });
db.messages_customer1.insert({ device: 456, dt: Date.now(), message: "baz" });

// insert some messages for customer 2
db.messages_customer2.insert({ device: 999, dt: Date.now(), message: "qux" });
db.messages_customer2.insert({ device: 888, dt: Date.now(), message: "wut" });

现在可以相对容易地找到给定客户的最新消息:

  • 通过请求和/或业务逻辑确定客户 ID
  • 带有客户ID(例如ID1),查询客户特定的集合

例如:

var query = "FOR m IN @@messages SORT m.dt DESC LIMIT 1 RETURN m";
var id = 1;
var params = { "@messages": "messages_customer" + id }
latestMessage = db._query(query, params).toArray()[0];

如果消息都是客户特定的,那么也无需为每个客户创建单独的数据库,因为所有客户特定的集合都可以进入同一个数据库。您当然应该关心对数据的访问控制,无论是通过应用程序业务逻辑还是Foxx

【讨论】:

  • 感谢您的回答!将设备分离为它们自己的集合是为了利用自动增量 ID。有没有办法用这个解决方案来保持它?此外,可能有数以千计的设备产生数以万计的消息。一个集合中的文档数量会不会有问题?
  • 您可能会在没有自动增量 ID 的情况下逃脱。 ArangoDB 中的每个文档都有一个_key 属性,当客户端应用程序没有提供该属性时,它会自动填充一些值。尽管对于客户端应用程序而言,服务器生成的内容是可预测的,但它可以让您稍后通过其唯一的_key 访问每个文档。如果你把消息时间保存在其他属性中,那么你仍然可以相对容易地找到最新消息。使用_key 按日期检索消息的另一个障碍是_key 上的索引是哈希索引(即未排序)。
  • 如果有客户端会有很多消息,那么这意味着集合里面有很多文档。它可能有助于限制每个集合的消息总量,例如通过在 ArangoDB 中使用上限约束。但我不确定您的商业案例是否允许这样做。如果没有,那么多收集选项(每个设备一个)可能是更好的选择,但这不会让您轻松找到 latest 消息。然后,您必须检查每个特定于客户端的消息集合以获取最新条目。
猜你喜欢
  • 2020-08-09
  • 1970-01-01
  • 1970-01-01
  • 2020-08-08
  • 1970-01-01
  • 2023-03-28
  • 1970-01-01
  • 2021-07-29
  • 2019-02-05
相关资源
最近更新 更多