MongoDB过滤器用于匹配和不匹配的条件

时间:2015-01-25 02:41:32

标签: mongodb mongoose mongodb-query aggregation-framework

我有一个场景我我可能需要使用$ cond根据字符串数组中是否存在现有属性来设置$ project(聚合)中的属性。

将以下数据作为简化示例......

var teamMemberFilter = ['Dave', 'Kate'];

[
    {
        ticketId: '1',
        ticketDesc: 'Dummy ticket 1',
        assignments: [
            {
                asignee: 'Team',
                email: 'supportinbox@mysite.com'
            },
            {
                asignee: 'Dave',
                email: 'dave@mysite.com'
            },
            {
                asignee: 'Kate',
                email: 'kate@mysite.com'
            }
        ]
    },
    {
        ticketId: '2',
        ticketDesc: 'Dummy ticket 2',
        assignments: [
            {
                asignee: 'Team',
                email: 'supportinbox@mysite.com'
            },
            {
                asignee: 'Rob',
                email: 'rob@mysite.com'
            }
        ]
    },
    {
        ticketId: '3',
        ticketDesc: 'Dummy ticket 3',
        assignments: [
            {
                asignee: 'Team',
                email: 'supportinbox@mysite.com'
            },
            {
                asignee: 'Dave',
                email: 'dave@mysite.com'
            },
            {
                asignee: 'Mark',
                email: 'mark@mysite.com'
            }
        ]
    }
]

我想要一个查询,它返回团队作业的所有票证,但没有团队成员的作业。

在上面的示例中,只有票证2应该返回,因为它具有团队分配,并且同一票证中唯一的其他分配属于Rob,而Rob不属于该团队(在teamMemberFilter中指定)。

1 个答案:

答案 0 :(得分:1)

当一个简单的查询足够时,不确定为什么你认为你需要使用聚合过滤器:

db.tickets.find({
    "$and": [
        { "assignments.asignee": "Team" },
        { "assignments.asignee": {"$nin": teamMemberFilter } }
    ]
})

匹配将“Team”作为“asignee”但在列出的数组中没有任何人的所有内容。

如果由于某种原因你真的需要在聚合管道中评估逻辑,那么你可以用逻辑运算符来应用它:

db.tickets.aggregate([
  { "$project": {
    "matched": {
      "$let": {
        "vars": {
          "names": { "$map": {
            "input": "$assignments",
            "as": "a",
            "in": "$$a.asignee"
          }}
        },
        "in": {
          "$and": [
            { "$eq": [ 
              { "$size": { "$setIntersection": [ "$$names", ["Team"] ] } },
              1
            ]},
            { "$eq": [ 
              { "$size": { "$setIntersection": [ "$$names", teamMemberFilter ] } },
              0
            ]},
          ]
        }
      }
    }
  }}
])

这只会在第二个文档上返回true,并且$map$setIntersection运算符会大大简化它们以处理数组内容。