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

需求 —— 字段内容权限

首先需要明白字段内容权限是什么。将 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
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,332评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,508评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,812评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,607评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,728评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,919评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,071评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,802评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,256评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,576评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,712评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,389评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,032评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,026评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,473评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,606评论 2 350