如何加速使用多个字符串过滤器的查询?

时间:2017-04-05 04:12:13

标签: mongodb

我在MongoDB 3.4中有一个集合来存储来自某个应用程序的所有用户的联系人。每个联系人都有一个很大的字符串字段列表(100+)。我使用MongoDB,但问题对任何其他引擎(MySQL,Elastic Search等)都有效

几乎所有检索联系人的查询都有相同的四个基本条件,例如 user_id base_field1 base_field2 base_field3 所以我用这些字段创建了一个复合索引来改进查询。基本查询如下所示:

db.contacts.find({
    user_id: 1434,
    base_field1: {$in: [0, 10]},
    base_field2: true,
    base_field3: "some value"
}).limit(10)

基本查询的执行时间很好(少于2秒),但请记住,有25K个联系人符合基本条件。

但是,该应用程序允许用户通过任何其他字段过滤联系人,甚至添加任意数量的过滤器。所有过滤器都使用 contains 运算符,因此查询看起来像:

db.contacts.find({
    user_id: 1434,
    base_field1: {$in: [0, 10]},
    base_field2: true,
    base_field3: "some value",
    field4: {$regex: "foobar", $options: "i"},
    field5: {$regex: "foobar", $options: "i"},
    field6: {$regex: "foobar", $options: "i"},
      .
      .
      .
}).limit(10)

因此,对于我们的要求,执行时间并不好(在9-10秒之间)。此外,正如您所料,增加过滤器数量也会增加执行时间:

有没有办法从设计和查询的角度加快查询速度?

是否有比MongoDB更好的其他数据库引擎来改善此类查询?

请在回复之前考虑以下注释和限制:

  • 文本索引在这里没用,因为如果我创建一个包含所有可能字段的复合文本索引但用户​​只过滤了 field4包含“foobar”那么结果可能包含“foobar”的联系人“在 field5
  • 只需创建一个化合物index with more than 31 fields is not possible in MongoDB
  • 为每个字段创建一个简单的索引没有意义,因为当用户按几个字段过滤时,MongoDB只会使用一个索引。您也可以创建only 64 indexes per collection
  • 我实际上是通过哈希键(user_id)使用MongoDB共享集群,但为了简化起见,我将问题减少到只有一个分片的范围,我的意思是,即使每个用户添加一个分片,问题也存在。

编辑我通过AND条件更改了OR条件( field4 OR field5 ...),这是真实的情况。

0 个答案:

没有答案