ArangoDb从所有收藏中获取最新文档

ArangoDb从所有收藏中获取最新文档,arangodb,aql,nosql,Arangodb,Aql,Nosql,我开始觉得我的数据建模有点不正确,因为我在查询数据时遇到了问题 目前我拥有的是一群客户(按照每个客户的数据库建模) 这些客户有一组设备:Device1…n(建模为每个设备的集合) 这些设备生成消息(在设备集合中建模为文档) 为了给客户提供良好的反馈,我现在希望支持检索客户的最新消息(每个设备一条消息) 我很难找到描述如何查询多个集合的文档,因为一个客户可以有1000个设备,我不想做1000个查询 谢谢 如果每个客户可以有1000个设备,并且设备消息存储在特定于设备的集合中,则搜索客户的最新消息需

我开始觉得我的数据建模有点不正确,因为我在查询数据时遇到了问题

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

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

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


谢谢

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

是否可以将给定客户的所有设备的消息放入一个特定于客户的集合中,并将设备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" });
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];
现在,找到特定客户的最新消息将相对容易:

  • 通过请求和/或业务逻辑确定客户id
  • 使用客户id(例如id
    1
    ),查询特定于客户的收款
例如:

// 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" });
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];

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

谢谢您的回答!将设备分离为它们自己的集合是为了利用自动增量id。有没有办法在这个解决方案中保持这一点?此外,可能有数千台设备可以创建数万条消息。一个集合中的文档数量是否会有问题?您可能没有自动递增id就可以离开。ArangoDB中的每个文档都有一个
\u key
属性,当客户端应用程序未提供该属性时,该属性将自动填充一些值。虽然生成的服务器对于客户端应用程序是可预测的,但它将使您能够在以后通过其唯一的
\u键访问每个文档。如果将消息时间保留在其他属性中,则仍然可以相对轻松地找到最新消息。使用
\u key
按日期检索邮件时的另一个障碍是
\u key
上的索引是散列索引(即未排序)。如果有客户机将有大量邮件,则这意味着其中包含许多文档的集合。它可能有助于限制每个集合的消息总量,例如通过在ArangoDB中使用cap约束。但我不确定你的商业案例是否允许这样做。如果不是,那么多个收集选项(每个设备一个)可能是更好的选择,但这不允许您轻松找到最新消息。然后,您必须检查每个特定于客户端的消息集合中的最新条目。为什么客户需要知道数千台设备的最新消息?您不能根据客户的请求,以增量方式为每个设备发送最新消息吗?(例如,动态加载和卸载数据的无限滚动,或简单分页)