如何找到两个键值的范围内有一个查询值的文档(How to find documents having

2019-10-22 03:19发布

我分析文本。 这些文本有标注(如“章”,“风景”,...)。 这些注释都在我的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

挑战三 :堪比挑战2我想只匹配完全被查询范围覆盖这些注解。 例如查询字符形式9800 to 30000只返回文档chapter 2

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

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

但我意识到,只为关键指标start被使用,即使我有一个复合索引startstop 。 有没有一种方法来创建我提到的三个问题较为充足的指标?

我想不久的地理空间索引,但我没有使用过,但。 我也只需要它的一维版本。

Answer 1:

对于挑战1,您所使用的查询是合适的,尽管你可能需要使用$lte$gte是包容性。

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

关于指标,它之所以选择使用该索引的start ,而不是复合索引中有树结构复合索引,这是很好的罗伯·摩尔在解释做这个答案 。 请注意,它仍然可以使用复合索引,如果你使用的hint()但查询优化器发现它更快地使用该指数start ,然后剔除不符合的范围,结果stop条款。

对于挑战2,你只需要使用一个明确的$or条款来覆盖情况下, stop边界内,当start是在范围之内,当startstop涵盖的范围。

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

对于挑战3,你可以使用非常相似的一个擂台1查询,但确保文档完全由指定范围的覆盖。

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


文章来源: How to find documents having a query-value within the range of two key-values