1

我正在考虑将时间序列数据捆绑在会话文档中。在每个会话中,都会有一系列事件。每个事件都有一个时间戳。我知道我可以在这些事件的时间戳上创建一个多键索引,但我很好奇 MongoDB 使用什么机制来防止同一文档在一个查询中出现两次。

为了澄清,想象一组包含以下文档的会话:

{
  _id: 'A',
  events: [
    {time: '10:00'},
    {time: '15:00'}
  ]
}
{
  _id: 'B',
  events: [
    {time: '12:00'}
  ]
}

如果我添加一个带有 的多键索引db.sessions.ensureIndex({'events.time' : 1}),我希望该索引的 b-tree 看起来像这样:

'10:00' => 'A'
'12:00' => 'B'
'15:00' => 'A'

如果我使用 查询集合{'events.time': {$gte: '10:00'}},MongoDB 会扫描 b-tree 并返回:

{ "_id" : "A", "events" : [  {  "time" : "10:00" },  {  "time" : "15:00" } ] }
{ "_id" : "B", "events" : [  {  "time" : "12:00" } ] }

Mongo如何防止文档A第二次显示为光标中的第三个结果?对于小型索引扫描,它可以只跟踪已经查看过哪些文档,但是如果索引很大,会发生什么?是否存在同一个文档在单个光标中多次出现的情况?

我的假设是它不会。Mongo 可以查看它正在扫描的文档,并通过检查索引数组中较早的条目来检测它已经在扫描中较早地匹配。但是,我在 MongoDB 文档中找不到任何提及此行为的内容,并且实际知道会发生什么很重要。

(注意:我确实知道,如果在扫描光标时修改了文档,则文档可能会多次出现在单个查询中。这不应该对时间序列数据的查询造成问题,其中时间戳永远不会被编辑。即使在扫描期间将新事件添加到会话中,如果 Mongo 使用类似于我上面提到的检测机制,它应该能够从查询结果中忽略移动的文档。)

4

1 回答 1

0

我在 MongoDB 文档中找不到任何关于这种行为的提及,并且真正知道会发生什么很重要。

文档中很少提及实现的内部,毕竟,您所描述的是预期的行为。

有代码可以对结果集进行重复数据删除,并且有一些测试可以确保它正常工作。毕竟,多键索引不是此类功能的主要用例 - 如果您的查询中有$or子句,则结果也必须进行重复数据删除。

于 2013-11-06T22:34:53.417 回答