【问题标题】:How to find documents having a query-value within the range of two key-values如何在两个键值范围内查找具有查询值的文档
【发布时间】:2015-02-28 08:16:46
【问题描述】:

我正在分析文本。这些文本有注释(例如“章节”、“风景”……)。这些注释在我的 MongoDB 集合annotations 中,例如

{
  start: 1,
  stop: 10000,
  type: chapter,
  details: {
    number: 1,
    title: "Where it all began"
  }
},
{
  start: 10001,
  stop: 20000,
  type: chapter,
  details: {
    number: 2,
    title: "Lovers"
  }
},
{
  start: 1,
  stop: 5000,
  type: scenery,
  details: {
    descr: "castle"
  }
},
{
  start: 5001,
  stop: 15000,
  type: scenery,
  details: {
    descr: "forest"
  }
}

挑战 1:对于文本中的给定位置,我想查找所有注释。例如查询字符1234 应该告诉我,那个

  • 在第一章内
  • 故事发生在城堡里

挑战 2:我也喜欢查询范围。例如查询9800 to 10101 形式的字符应该告诉我,它涉及chapter 1chapter 2scenery forest

挑战 3:类似于 挑战 2 我只想匹配那些完全被查询范围覆盖的注释。例如查询9800 to 30000形式的字符应该只返回文档chapter 2

对于挑战 1,我尝试简单地使用 $lt$gt。例如:

db.annotations.find({start: {$lt: 1234}, stop: {$gt: 1234}});

但我意识到,即使我有 startstop 的复合索引,也只使用键 start 的索引。有没有办法为我提到的三个问题创建更充分的索引?

我很快想到了地理空间索引,但我还没有使用它们。我也只需要它的一维版本。

【问题讨论】:

    标签: mongodb indexing geospatial compound-index


    【解决方案1】:

    对于挑战 1,您使用的查询是合适的,但您可能希望使用 $lte$gte 以包含在内。

    db.annotations.find({ "start": { "$lt": 1234 }, "stop": { "$gt": 1234 }});
    

    关于索引,它选择使用start 上的索引而不是复合索引的原因与复合索引的树结构有关,Rob Moore 在this answer 中很好地解释了这一点。请注意,如果您使用hint(),它仍然可以使用复合索引,但是查询优化器发现使用start 上的索引会更快,然后清除与stop 子句的范围不匹配的结果.

    对于挑战2,您只需要使用显式的$or 子句来涵盖stop 在界限内、start 在界限内和@987654332 时的情况@ 和 stop 包含边界。

    db.annotations.find({
        "$or": [
            { "stop": { "$gte": 9800, "$lte": 10101 }},
            { "start": { "$gte": 9800, "$lte": 10101 }},
            { "start": { "$lt": 9800 }, "stop": { "$gt": 10101 }}
        ]
    });
    

    对于挑战 3,您可以使用与 挑战 1 中的查询非常相似的查询,但要确保文档完全被给定的边界所覆盖。 p>

    db.annotations.find({ "start": { "$gte": 9800 }, "stop": { "$lte": 30000 }});
    

    【讨论】:

    • 我在您发布的链接中找不到 rob moore 的答案(链接错误?)。提示():mongo 是否也使用startstop 的信息?还是仅使用start: {$lte: ...} 的信息。
    • 对不起。现在修复链接。我不知道使用hint() 优化器是否会使用这两种信息或仅使用前缀。您可以尝试分析这两个查询,看看是否有任何区别。
    猜你喜欢
    • 2016-10-29
    • 1970-01-01
    • 1970-01-01
    • 2021-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-02
    相关资源
    最近更新 更多