更好的过滤集合模式

时间:2014-06-23 22:17:19

标签: mongodb meteor

我有一个名为Games的集合,我希望用户使用复选框过滤集合。每次选中/取消选中复选框时,都会调用流星订阅以显示相应的Games

以下是订阅可能的示例(不合适的mongo代码):

{region: ['east','west','eu'], skill: ['casual','amatuer','pro'], gamemode: ['ctf','dm','etc']}

在这个特定游戏中,您可以按区域,技能和游戏模式进行过滤,每个游戏都有多种组合。

编辑:

我需要创建适当的选择器,具体取决于选中的复选框。

首先,我抓住已检查的复选框 - 为每个组 - 并将它们放入一个数组中,然后将该数组设置为会话变量。

// Gamemode Group
'click .mode input[type=checkbox]': function(ev, tpl) {
    var mode = tpl.$('.mode input:checked').map(function () {
        return $(this).val();
    });

    var modeArray = $.makeArray(mode);
    Session.set('dotaMode', modeArray);
    returnFilterQuery();
},

然后我检查每个groups数组以查看它们是否已填充,如果是,则将它们添加到最终选择器(query),我将传入订阅。我的问题是我必须检查每个可能的场景,除了if语句之外什么都没有,一旦我开始添加更多的组(游戏模式,区域,技能等)来搜索,就会有更多的组合

function returnFilterQuery(){
    //check all fields and create a query object
    var query = { game: 'dota' };
    var gamemode = Session.get('dotaMode');
    var region = Session.get('dotaRegion');
    var skill = Session.get('dotaSkill');

    // if no region or skill is selected, show user all
    if (region.length && skill.length && gamemode.length) {
        query.region = { $in: region };
        query.skill = { $in: skill };
        query.gamemode = { $in: gamemode };
    } else if (region.length && !skill.length && gamemode.length) {
        query.region = { $in: region };
        query.gamemode = { $in: gamemode };
    } else if (!region.length && skill.length && gamemode.length) {
        query.skill = { $in: skill };
        query.gamemode = { $in: gamemode };
    } else if (!region.length && !skill.length && gamemode.length) {
        query.gamemode = { $in: gamemode };
    } else if (region.length && skill.length && !gamemode.length) {
        query.region = { $in: region };
        query.skill = { $in: skill };
    } else if (region.length && !skill.length && !gamemode.length) {
        query.region = { $in: region };
    } else if (!region.length && skill.length && !gamemode.length) {
        query.skill = { $in: skill };
    }

    return Session.set('dotaFilter', query);
};

希望这一切都有道理。我确信必须有更好的方法,我现在无法想到什么。感谢。

1 个答案:

答案 0 :(得分:3)

由于DotA参考,我感到特别鼓舞回答这个问题。 :)

因此,如果我正确理解了问题,您不需要检查每个组合,而是根据三个会话变量的内容重复向query对象添加键。我认为以下内容在逻辑上等同于您上面的returnFilterQuery函数。

var returnFilterQuery = function() {
  var query = {game: 'dota'};

  var modifyQueryIfArray = function(key, sessionKey) {
    var value = Session.get(sessionKey);
    if (!_.isEmpty(value))
      query[key] = {$in: value};
  };

  modifyQueryIfArray('gamemode', 'dotaMode');
  modifyQueryIfArray('region', 'dotaRegion');
  modifyQueryIfArray('skill', 'dotaSkill');

  return Session.set('dotaFilter', query);
};

请注意,如果会话变量不是数组,isEmpty可能比length更安全。