【问题标题】:MongoDB row index limit query like SQLMongoDB 行索引限制查询,如 SQL
【发布时间】:2017-07-02 15:12:25
【问题描述】:

我想在某些条件下检索包含指定记录的列表,并且只检索该记录之前的一些记录和该记录之后的一些记录。有什么解决办法吗?

例如,我有一个 MongoDB 架构 { id, date, section } 数据集:

100, 26 Aug 2014 11:00, A
110, 26 Aug 2014 11:01, A
140, 26 Aug 2014 12:00, A
141, 27 Aug 2014 12:00, B
200, 30 Aug 2014 11:00, A
210, 01 Sep 2014 11:01, B
290, 02 Sep 2014 12:00, A
300, 26 Sep 2014 12:00, A
301, 27 Oct 2014 12:00, B
302, 30 Oct 2014 11:23, A
410, 01 Oct 2014 15:01, B
590, 02 Oct 2014 12:00, A
600, 26 Nov 2014 00:00, A

我想要一个列表,其中包含一个唯一的 id = 300 和 3 条之前的记录和 3 条之后的记录,id = 300,在 A 部分下按日期排序。

输出:

140, 26 Aug 2014 12:00, A
200, 30 Aug 2014 11:00, A
290, 02 Sep 2014 12:00, A
300, 26 Sep 2014 12:00, A <-- middle
302, 30 Oct 2014 11:23, A
590, 02 Oct 2014 12:00, A
600, 26 Nov 2014 00:00, A

我有一个愚蠢的方法:

  1. 通过 A 部分获取指定 id = 300 的日期(假设是 2014 年 9 月 26 日 12:00)
  2. 设置查询以查找日期大于等于 2014 年 9 月 26 日 12:00 的记录,按日期排序,限制为 3 条记录。
  3. 设置查询以查找日期小于 2014 年 9 月 26 日 12:00 的记录,按日期排序,限制为 3 条记录。
  4. 合并两个列表。

有没有更好的方法来在查询中检索这种列表或获得更好的性能?谢谢。

【问题讨论】:

  • id 与日期的方向是否相同?例如,id(300) > id(290),然后 date(300) >= date(290)。而且,是否有可能为不同的 id 重复日期?
  • @Wizard id 是唯一的,假设可以将新记录插入为 {610, 26 Oct 2014 00:00, A}
  • 因此,不可能通过 id 在一个查询中找到,因为日期未知。您的方法应该适合这种情况,您可以通过添加索引来提高性能,例如{section:1, date:1, id:1}
  • 请更准确地定义排序是什么。什么定义之前或之后?是_ids 吗?是按时间顺序吗?如果它是按时间顺序排列的,那么要找到一个给定文档的间隔,其范围由其中的文档数量决定,你将不得不采用你的“愚蠢”方法(我认为这并不愚蠢)。但是您可能还需要考虑一种具有更自然限制的不同类型的查询,例如根据您的用例按开始和结束日期定义范围。
  • @Wizard 谢谢。然后我将实施我的方法并设置有点索引

标签: mongodb mongodb-query


【解决方案1】:

让我们的架构名称为USER。您可以使用下面的 mongo db 查询来获取结果

$sort函数:

  • 1 代表升序
  • -1 代表降序

参考文档:$Sort Documentation

查询将是:

db.user.aggregate({$match : { "id" : 300}},{$sort : {"date": 1 }},{$skip : 0},{$limit : 10});

$skip 值将是您第一次查询后的limit

db.user.aggregate({$match : { "id" : 300}},{$sort : {"date": 1 }},{$skip : 10},{$limit : 10});

参考文档:Aggregation Documentation

【讨论】:

  • 谢谢。但是,我认为您误解了我的问题。您将找出所有匹配 id = 300 的结果,但 id = 300 实际上是唯一的,我想要得到的是 id = 300 之前的 10 条记录和 id = 300 之后的 10 条记录。
【解决方案2】:

$skip and $limit in aggregation framework

这里是使用跳过和限制的一个很好的例子,它应该可以帮助您实现SELECT TOP XLIMIT X

注意:我假设您要使用基于此问题标记的聚合框架。

我认为应该这样做

x = 300;
db.user.aggregate({$match : { "id" : {$lte: x+10,$gte: x-10 }},{$sort : {"date": 1 }}});

【讨论】:

  • 我已阅读,但我很想形成聚合函数。你有什么想法吗?
  • 我添加了一个示例,说明如何根据 id 获取范围。
  • 感谢您的回答。但是,正如您可以看到我展示的示例,订单应该是日期而不是 id,并且假设可以将新记录插入为 {610, 26 Oct 2014 00:00, A}
  • 好了,将日期排序添加到查询中。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-03
  • 1970-01-01
  • 2015-11-05
  • 1970-01-01
相关资源
最近更新 更多