1. 写在之前
    ElasticSearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java开发的,并作为Apache许可条款下的开放源码发布,是当前流行的企业级搜索引擎。设计用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便。
    在之前在项目开发中的不同的查询条件都需要单独些Java bean去封装查询语句,后面就想能不能让es也支持类似与sql where name=xxx and age=20这类的过滤条件。所以在这儿就写了个解析表达式同时生成es能够支持的query dsl的小工具 支持的操作符号有==,!= ,<,>,>=,<= 同时还支持加括号增加查询条件优先级的功能。
  2. 实现
    源码中的conditionNode用到了二叉树的结构,表达不是很清楚,直接上个列子吧,比如我要查询的表达式为:

    name==yang and age==20

    生成的conditionNode 的json结构为

    {
    "op":"eq",
    "type":"normal",
    "left":{
        "field":"name",
        "value":"yang",
        "op":"eq",
        "type":"normal"
    },
    "right":{
        "field":"age",
        "value":"20",
        "op":"eq",
        "type":"normal"
    },
    "relation":"and"
    }

    可以看到在最外层的conditionNode的左右两个节点封装单独的两个conditionNode ,且其关系为and,最后将 解析后的condition生成query dsl:

    {
      "bool" : {
    "must" : [
      {
        "bool" : {
          "must" : [
            {
              "query_string" : {
                "query" : "name:\"yang\""
              }
            }
          ],
          "disable_coord" : false,
          "adjust_pure_negative" : true,
          "boost" : 1.0
        }
      },
      {
        "bool" : {
          "must" : [
            {
              "query_string" : {
                "query" : "age:\"20\"",
                
              }
            }
          ],
          "disable_coord" : false,
          "adjust_pure_negative" : true,
          "boost" : 1.0
        }
      }
    ],
    "disable_coord" : false,
    "adjust_pure_negative" : true,
    "boost" : 1.0
      }
    }

    如果只是支持顺序解析倒也没有什么特别的,这里举个添加括号提高查询条件优先级的列子:
    expression : (name==yang and age>20) or (name == wang and age<=18)
    解析后的conditionNode为:

    {
    "op":"eq",
    "type":"normal",
    "left":{
        "op":"eq",
        "type":"normal",
        "left":{
            "field":"name",
            "value":"yang",
            "op":"eq",
            "type":"normal"
        },
        "right":{
            "field":"age",
            "value":"20",
            "op":"gte",
            "type":"normal"
        },
        "relation":"and"
    },
    "right":{
        "op":"eq",
        "type":"normal",
        "left":{
            "field":"name",
            "value":"wang",
            "op":"eq",
            "type":"normal"
        },
        "right":{
            "field":"age",
            "value":"18",
            "op":"lte",
            "type":"normal"
        },
        "relation":"and"
    },
    "relation":"or"
    }

    最后根据该conditionNode生成的dsl语句为:

    {
      "bool" : {
    "should" : [
      {
        "bool" : {
          "must" : [
            {
              "bool" : {
                "must" : [
                  {
                    "query_string" : {
                      "query" : "name:\"wang\""
                    }
                  }
                ],
                "disable_coord" : false,
                "adjust_pure_negative" : true,
                "boost" : 1.0
              }
            },
            {
              "bool" : {
                "must" : [
                  {
                    "range" : {
                      "age" : {
                        "from" : null,
                        "to" : "18",
                        "include_lower" : true,
                        "include_upper" : true,
                        "boost" : 1.0
                      }
                    }
                  }
                ],
                "disable_coord" : false,
                "adjust_pure_negative" : true,
                "boost" : 1.0
              }
            }
          ],
          "disable_coord" : false,
          "adjust_pure_negative" : true,
          "boost" : 1.0
        }
      },
      {
        "bool" : {
          "must" : [
            {
              "bool" : {
                "must" : [
                  {
                    "query_string" : {
                      "query" : "name:\"yang\""
                    }
                  }
                ],
                "disable_coord" : false,
                "adjust_pure_negative" : true,
                "boost" : 1.0
              }
            },
            {
              "bool" : {
                "must" : [
                  {
                    "range" : {
                      "age" : {
                        "from" : "20",
                        "to" : null,
                        "include_lower" : false,
                        "include_upper" : true,
                        "boost" : 1.0
                      }
                    }
                  }
                ],
                "disable_coord" : false,
                "adjust_pure_negative" : true,
                "boost" : 1.0
              }
            }
          ],
          "disable_coord" : false,
          "adjust_pure_negative" : true,
          "boost" : 1.0
        }
      }
    ],
    "disable_coord" : false,
    "adjust_pure_negative" : true,
    "boost" : 1.0
      }
    }
    冗余的东西有点多,大家将就着看吧,这里贴上源码地址

https://github.com/jacobyangs...

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐