使用访问控制过滤器

时间:2016-06-06 18:26:00

标签: elasticsearch

我的Elasticsearch索引中的每个文档都有两个包含用户ID的访问控制列表。一个是允许列表,另一个是拒绝列表。我正在尝试将过滤器添加到考虑这些ACL的给定查询中。我以为我可以对给定查询使用bool子句must子句,允许列表使用filter子句,拒绝列表使用must_not子句。到目前为止我所拥有的(用户1的例子):

{
"bool" : {
"must" : {
  [given query]
},
"filter" : [ {
  "match" : {
    "acl.allow" : {
      "query" : "/user/1",
      "type" : "boolean"
    }
  }
}],
"must_not" : [ {
  "match" : {
    "acl.deny" : {
      "query" : "/user/1",
      "type" : "boolean"
    }
  }
}]
}
}

不幸的是,此查询未返回所需的结果。它返回未在其允许列表中列出用户1的对象(我不理解的行为)。此外,它(显然)忽略具有空访问控制列表的对象(任何人都应该可以看到)。有什么建议可以解决这个问题吗?

1 个答案:

答案 0 :(得分:1)

我明白了。首先,由于其分析器,使用match对于这种查询来说并不是一个很好的解决方案。使用term让我感到困惑,为什么我没有得到任何结果。如果相应字段设置为not_analyzed,则术语查询仅返回结果。因此我改变了我的映射:

"acl": {
        "properties": {
          "allow": {
            "type": "string",
            "index": "not_analyzed"
          },
          "deny": {
            "type": "string",
            "index": "not_analyzed"
          }
        }
      }

我的第二个问题处理对象具有空ACL,对任何人都可见 - 使用exists嵌套在must_not嵌套在bool中来解决。建议将其替换为已弃用的missing查询。我的最终查询看起来像这样,并通过了我能想到的所有与ACL相关的测试。

{
"bool" : {
"must" : {
  [given query]
},
"filter" : {
  "bool" : {
    "should" : [ {
      "terms" : {
        "acl.allow" : [ "/user/1" ]
      }
    }, {
      "bool" : {
        "must_not" : {
          "exists" : {
            "field" : "acl.allow"
          }
        }
      }
    } ]
  }
},
"must_not" : {
  "terms" : {
    "acl.deny" : [ "/user/1" ]
  }
}
}
}