美文网首页
Elasticsearch 字段内容权限之布尔过滤器

Elasticsearch 字段内容权限之布尔过滤器

作者: xuxiangwork | 来源:发表于2018-02-26 18:28 被阅读0次

    需求 —— 字段内容权限

    首先需要明白字段内容权限是什么。将 Elasticsearch 暂时当作数据库进行理解。假设数据库中有一张表格存储着国内的银行等金融企业的信息,表格包含企业名称、企业成立时间、企业董事长年龄等信息。对于所有查询该表格信息的用户,比如对用用户 1 ,希望他只能访问企业名为 "中国建设银行" 的信息,或者希望他只能访问企业成立时间在近10年内的企业。只能访问 "中国建设银行" 或 只能获取近10年成立的企业,这就是字段内容权限。

    ES 布尔过滤器

    ES 的过滤器在查询时,会做一个判断:是否应该将文档添加到结果集?通过这个判断,可以实现对用户的访问控制。
    bool 过滤器由三部分组成:

    
    {
       "bool" : {
          "must" :     [],
          "should" :   [],
          "must_not" : [],
       }
    }
    
    

    must:所有分句都必须匹配,与 AND 相同。

    must_not:所有分句都必须不匹配,与 NOT 相同。

    should:至少有一个分句匹配,与 OR 相同。

    提示:bool 过滤器的每一个部分都是可选的(你可以只保留一个 must 分句),而且每一个部分可以包含一到多个过滤器。

    ES 布尔过滤器示例

    在显示查询中,可能希望过滤过个值或字段,例如希望在 Elasticsearch 中表达如下的 SQL 语句。

    
    SELECT product
    FROM   products
    WHERE  (price = 20 OR productID = "XHDK-A-1293-#fJ3")
      AND  (price != 30)
    
    

    希望过滤掉价格(price)为30的,而且价格为20的或者产品编号(productID)为 "XHDK-A-1293-#fJ3" 的产品。

    结合 Elasticsearch 的 should 相当于 or,must_not 相当于 not,ES 表达上述 SQL 如下:

    
    GET /my_store/products/_search
    {
       "query" : {
          "filtered" : {
             "filter" : {
                "bool" : {
                  "should" : [
                     { "term" : {"price" : 20}},
                     { "term" : {"productID" : "XHDK-A-1293-#fJ3"}}
                  ],
                  "must_not" : {
                     "term" : {"price" : 30}
                  }
               }
             }
          }
       }
    }
    
    

    上述代码中的 "term" 相当于精确匹配的意思。其含义是 "price" 这个字段精确匹配 20,"productID" 精确匹配 "XHDK-A-1293-#fJ3" 。相当于数学公式中的 "=" 符号的意思。

    查询操作类型

    如前面提到的 term 精确匹配,目前支持的查询操作类型为:term(精确匹配)、match(匹配)、match_phrase(短语匹配)、range(范围查询)。

    term 精确匹配

    term 对完全匹配的意思,对于数字类型的字段,就是单纯的 "=" 的关系,但对于字符串类型的字段而言,仅字段内容为不被分析时,才是等号的关系。

    如一个索引定义如下,打入如下的数据:

    
    PUT my_index
    {
      "mappings": {
        "my_type": {
          "properties": {
            "full_text": {
              "type":  "string"
            },
            "exact_value": {
              "type":  "string",
              "index": "not_analyzed"
            }
          }
        }
      }
    }
     
    PUT my_index/my_type/1
    {
      "full_text":   "Quick Foxes!",
      "exact_value": "Quick Foxes!" 
    }
    

    对于 Elasticsearch 而言,full_text 是被分析过的,索引中,该字段是[quick, foxes],而 exact_value 中存的则是 [Quick Foxes!]。

    match 匹配查询

    match 本质是只要内容包含任意查询关键字就匹配查询。用例子理解 match 较好理解,比如查询关键字是 "He is"。

    
    GET /test/student/_search
    {
      "query": {
        "match": {
          "description": "He is"
        }
      }
    }
    

    对于 Elasticsearch 而言,关键字实际是 [he,is],字段 description 如下的都会匹配到。

    
    "description": "He is passionate."
    "description": "He is a big data engineer."
    "description": "He works very hard because he wanna go to Canada."
    "description": "She is so charming and beautiful."
    
    

    实际就是只要包含任意一个关键字就可以了。

    match_phrase 短语匹配

    match_phrase 是短语匹配的意思。match 其只要包含任意查询关键字就匹配,但有时候希望字段包含和查询字段一模一样的内容。match_phrase 就是字段精确包含查询字段。

    如上 match 的查询,如果采用 match_phrase 进行查询,就只有如下匹配:

    
    "description": "He is passionate."
    "description": "He is a big data engineer."
    
    

    match_phrase 和 term 相比,前者是包含关系,后者是相等关系。

    range 范围查询

    range 比较好理解,就是满足一定范围的字段能够被查询出来。如最开始定义的用户仅能查询近10年的企业,就可以用 range 进行限定。

    
    GET /test/student/_search
    {
      "query": {
        "range": {
          "established_time": {"gte": "10 years ago"}
        }
      }
    }
    
    

    字段内容权限的编写

    上述说明都是为了正确的编写字段内容权限。

    格式如下:

    
    {
        "and" : [],
        "or" : [],
        "not" : [],
    }
    
    

    为了让用户易于理解,采用 "and" 替换 "must"、 "or" 替换 "should"、 "not" 替换 "must_not"。

    其中每一个 and、or、should等字段后的数组内容如下:

    
    [
        {"qt":"match_phrase","value":"工商银行"},
        ...
        {"qt":"match_phrase","value":"建设银行"},
    ]
    
    

    字段 "qt" 是查询操作类型,有 term(精确匹配)、match(匹配)、match_phrase(短语匹配)、rtd——range(范围查询)。

    字段 "value" 是该字段查询类型的值。值得注意的是 rtd 的值是数字,一般为天。

    如最初的金融企业信息表那样,希望用户不能查询招商银行的信息,则对于企业名(enterprise_name)这个字段。

    字段权限内容编写为:

    
    {
        "not" : [{"qt":"match_phrase","value":"招商银行"}],
    }
    
    

    又如希望用户仅能查询成立时间(established_time)在90天内的企业信息,则对 "established_time" 字段的权限内容为:

    
    {
        "and" : [{"qt":"rtd","value":"90"}],
    }
    
    

    又如希望用户仅能查询查询企业名为中国银行、建设银行的,对 "enterprise_name" 字段的权限内容为

    
    {
        "or" : [{"qt":"match_phrase","value":"中国银行"},{"qt":"match_phrase","value":"建设银行"}],
    }
    
    

    字段内容权限验证 json shema

    
    type: object
    properties:
        and:
            type: array
            minItems: 1
            items:
                type: object
                required: [qt, value]
                properties:
                    qt:
                        type: string
                        enum: ["term", "match", "match_phrase", "rtd"]
                    value:
                        type: string
                        maxLength: 255
                additionalProperties: false
            uiqueItems: true
        or:
            type: array
            minItems: 1
            items:
                type: object
                required: [qt, value]
                properties:
                    qt:
                        type: string
                        enum: ["term", "match", "match_phrase", "rtd"]
                    value:
                        type: string
                        maxLength: 255
                additionalProperties: false
            uiqueItems: true
        not:
            type: array
            minItems: 1
            items:
                type: object
                required: [qt, value]
                properties:
                    qt:
                        type: string
                        enum: ["term", "match", "match_phrase", "rtd"]
                    value:
                        type: string
                        maxLength: 255
                additionalProperties: false
            uiqueItems: true
    additionalProperties: false
    

    相关文章

      网友评论

          本文标题:Elasticsearch 字段内容权限之布尔过滤器

          本文链接:https://www.haomeiwen.com/subject/smayxftx.html