创建涉及多个过滤器,排序和限制的复杂Mongoose / Mongo查询的最佳方法是什么?

时间:2014-09-04 08:10:05

标签: mongodb indexing mongoose

我尝试使用多个过滤条件构建复杂查询来获取数据。虽然我的代码在小型测试中运行良好,但我正在扩展到更多用户并且数据查询变得慢得令人无法接受(例如,完成请求需要20-30秒)。我不确定我是否应该使用索引,或者它们是否适用于这样的复杂查询,或者我是否应该使用多个单独的查询,或者我需要完全重构查询或数据。下面的代码是一个示例查询,比如查找用户ID在给定数组中但在其他数组中没有的用户,以及谁的首选项符合某些过滤条件,以及谁在给定的地理位置。我很确定我在这里违反了一些基本规则,但我是一个相对新手,所以任何帮助都非常感谢!特别是,如果索引是需要的,那么在这个示例案例中,它有助于举例说明如何使用索引。谢谢!

User.find({
  $and: [
    { userid: {$in: array1} },
    { userid: {$nin: array2} },
    { userid: {$nin: array3}},
    { userPref1: {$ne: userPref} },
    { userPref2: {$ne: userPref2} },
    { latlon : {"$within" :           
            {"$center" : [userlocation , distance ]}
          } }
          ]},
    .sort('-hasAccount -hasActions')
    .limit(max)
    .exec(function(...){});

1 个答案:

答案 0 :(得分:3)

  1. "查找用户ID在给定数组中但在其他数组中没有的用户"

    合并" {userid:{$ in:array1}},{userid:{$ nin:array2}},{userid:{$ nin:array3}}"合而为一。获取array1但不包含array2& array3的用户ID到array4,然后使用{userid:{$ in:array4}}

  2. "谁的偏好符合某些过滤条件"

    如果只有2个userPref,则构建复合索引就可以了。但如果有几十个......没办法。你必须在没有索引的情况下留下不重要的userPref,这肯定会使查询变慢。

  3. "谁在某个地理位置"

    2d索引是必要的。

  4. 要点:

    if(num of userPrefs < M) // I would set M = 3  
        build index: {loc:"2d", userid:1, userPref1:1, userPref2:1} or
        build index: {loc:"2d", userid:1, userPref1:1};
        sort({loc:"2d", userid:1, userPref1:1});
    else
        reduce num of userPrefs;
    

    BTW:按其他顺序排序而不是{loc:&#34; 2d&#34;,userid:1,userPref1:1}也会减慢查询速度。