Meteor和Mongo以及标签过滤器

问题描述:

流星应用程序,我有一个有标签字段的mongo集合。Meteor和Mongo以及标签过滤器

[{name: "ABC", tags: {"@Movie", "#free", "!R"}}, 
{name: "DEF", tags: {"@Movie", "!PG"}}, 
{name: "GHI", tags: {"@Sports", "#free"}}] 

在我的用户界面上,根据标签名称的第一个字母,有三组复选框被动态填充。

filter group 1: [ ]Movie [ ] Sports 
filter group 2: [ ]free 
filter group 3: [ ]PG [ ]R 

滤波器逻辑如下:

  • 如果滤波器组是空的,则没有通过从滤波器组中的任何复选框被选中该滤波器组
  • IF滤波器,然后应用该过滤器
  • $并且应该应用于过滤器组之间(如果电影和R被选中,则只应选择标记名为“!Movie”和“#free”的文档

我正在努力构建遵循上述逻辑的mongo标准参数。我的代码目前看起来像有大量嵌套ifs的意大利面条(伪代码)

if(filter_group1 is empty)then if(filter_group2 is empty)then mongo_criteria = {_id:$ in:$(“input:checked”, “.filtergroup1”)。map(function(){return this.value})}

这样做的正确方法是什么?

首先,我敢肯定,你的意思是“标签”其实是一个数组,因为否则的结构将是无效的:

{ "name": "ABC", "tags": ["@Movie", "#free", "!R"]}, 
{ "name": "DEF", "tags": ["@Movie", "!PG"]}, 
{ "name": "GHI", "tags": ["@Sports", "#free"]} 

它存储的“标签”的数据这样一个新的想法,但它似乎你的程序逻辑构建查询需要知道,至少有“三种”可能的条件需要在$and组合中考虑。

在最简单的形式,你只允许一个选择每个过滤器组,然后你可以逃脱与$all运算符出来。只需简单的MongoDB外壳符号为简洁:

db.collection.find({ "tags": { "$all": [ "@Movie", "!R" ] } }) 

的问题存在,如果你想在一组多重选择,比如说评级例如,那么这将无法得到一个结果:

db.collection.find({ "tags": { "$all": [ "@Movie", "!R", "!PG" ] } }) 

实际上没有任何项目包含这些评级值,所以这不会有效。所以你宁愿这样做:

db.collection.find({ "$and": [ 
    { "tags": { "$in": [ "@Movie" ] } }, 
    { "tags": { "$in": [ "!R", "!PG" ] } } 
]) 

这将正确匹配所有电影与“R”和“PG”的评级标签。延伸到其他的基团基本上是推动另一个数组项到$and表达式:

db.collection.find({ "$and": [ 
    { "tags": { "$in": [ "@Movie" ] } }, 
    { "tags": { "$in": [ "!R", "!PG" ] } }, 
    { "tags": { "$in": [ "#free" ] } 
]) 

获取仅包含每个这些滤波器的匹配值“类型”的文件,因此,“PG”电影是不免费和“体育”被过滤出来,而不是添加到选择。

构建查询的基础知识使用每个过滤器组中的$in的一组选择选项。当然,当过滤器组中存在选择时,您只能附加到$and阵列。

所以用碱$and像这样开头:

var query = { "$and":[{}] }; 

然后在每一个每个滤波器组在检查选项添加到了自己在:

var inner = { "tags": { "$in": [] } }; 
inner.tags["$in"].push(item); 

然后追加到基本查询:

query["$and"].push(inner); 

冲洗并重复每个项目。这是完全有效的,因为基本查询只会选择所有未经过滤的,这也是不增建逻辑有效:

db.collection.find({ "$and": [ 
    { }, 
    { "tags": { "$in": [ "@Movie" ] } }, 
    { "tags": { "$in": [ "!R", "!PG" ] } }, 
    { "tags": { "$in": [ "#free" ] } 
]) 

所以这真的可以归结为MongoDB的了解它的查询敷设渠道。这实际上只是构建数据结构中的简单JavaScript数组操作。这是所有的MongoDB查询真的是。

+0

很好 - 这部分解决了我建立mongo标准的问题。我仍然需要遍历所有的筛选器类别,并且只为那些至少有一项检查的项目插入标准。另外,我实际上将标签存储在单独的集合上 – 2014-11-03 13:18:25