在 CosmosDB 中存储资产跟踪数据的好方法



我正在Azure上构建一个简单的资产跟踪应用程序,该应用程序需要捕获周围的详细信息

  1. 资产信息,
  2. 其当前位置
  3. 具有资产 ID 及其位置的时序数据。 以跟踪一段时间内的资产。可能持续数年

有问题的资产将定期流式传输其位置详细信息,例如每 10 秒一次Event Grid我想将此数据流式传输到存档以供将来分析,同时还要查询1 kmgeospatial距离内的其他资产并向他们发送通知。

因此,我希望了解将此信息存储在CosmosDB中的最佳方法是否有效,将其存储在一个集合中,例如按资产 ID 分区

Asset : {
AssetId : "123456",
RegisteredAddress : "123, abc xyz",
ZipCode : "12345"
MobileNo: "32423432432"
CurrentLocation: Point {12, 123}
LocationHistory:[
{Timestamp: 1/1/2019 12:20:10, Location: Point{12, 123}},
{Timestamp: 1/1/2019 12:20:20, Location: Point{12, 123}},
{Timestamp: 1/1/2019 12:20:30, Location: Point{12, 123}},
{Timestamp: 1/1/2019 12:20:40, Location: Point{12, 123}},
{Timestamp: 1/1/2019 12:20:50, Location: Point{12, 123}},
]
}

或者最好维护一个单独的集合来管理LocationHistory

LocationHistory: {
AssetId: 12345, 
Timestamp: "1/1/2019 12:20:10", 
Location: Point{12, 123}
}

顺便说一句,我是Document store新手,所以如果可能的话,请随时提出更好的选择。

我真的希望在这里最大限度地降低我的运营成本,那么上述 2 种方法如何影响我的总体运营成本。假设我使用 Azure 函数对事件网格事件进行触发并更新此集合。

更新 1:

根据Joel Oughton在下面的回答,我尝试将有关资产的元数据以及跟踪详细信息作为单独的文档移动,但位于单个集合上。为此,我进行了以下更改:

  1. 我为所有类添加了额外的 2 个属性,即_PartitionKey_Service
  2. 在存储事件之前,我正在构建和更新_PartitionKey

我现在使用以下代码来捕获资产元数据:

assetInfo.LastUpdated = DateTimeOffset.Now;
assetInfo._PartitionKey = $"assets_{assetInfo.Address.State.ToLower()}_{assetInfo.Address.City.ToLower()}";
assetInfo._Service = "assets";
Uri collectionUri = UriFactory.CreateDocumentCollectionUri(config.DatabaseName, config.CollectionName);
var documnent = await DBUtility.GetDocumentClient().UpsertDocumentAsync(collectionUri, assetInfo);

以与存储跟踪信息相同的方式,我在下面使用此代码:

tracking.UnixTimestamp = DBUtility.GetEpochTimeMillis(DateTime.UtcNow);
tracking.Id = $"{tracking.AssetId.ToLower()}_{tracking.UnixTimestamp}";
tracking.Timestamp = DateTime.Now.ToString("o");
tracking._PartitionKey = $"tracking_{tracking.AssetId.ToLower()}_{DateTime.Today.ToString("D")}";
tracking._Service = "trackings";
Uri collectionUri = UriFactory.CreateDocumentCollectionUri(config.DatabaseName, config.CollectionName);
var documnent = await DBUtility.GetDocumentClient().UpsertDocumentAsync(collectionUri, tracking);
requestCharge += documnent.RequestCharge;  

这个接缝运行良好,但是我很难决定如何查询所有远离给定坐标1 Km的资产。问题是我需要在使用ST_DISTANCE之前从每个资产中选择最新的跟踪事件。

有人可以建议我如何创建一个查询,该查询能够找到在这种情况下与给定Point1 Km的所有资产详细信息。

Cosmos DB 具有文档大小限制,并且性能可能会随着文档的增加而下降。

我会存储一个包含资产 ID、地址等的元数据类型文档和一个包含资产 ID、时间戳和位置的文档。

此外,可以使用最新的时间戳位置确定当前位置,而不必在每次更改时更新元数据记录。

这种结构将允许高效的读写操作,并防止文档大小限制成为问题。

如果要优化运营成本并使用 .NET,可以使用 https://github.com/cloud-maker-ai/Nebula(免责声明:我是作者)。否则,请确保整个 RU 在多个集合之间共享,或者两种文档类型都存储在具有逻辑分隔的同一集合中。

最新更新