Elasticsearch Query DSL (语法)

Elasticsearch 提供了一个可以执行查询的 Json 风格的 DSLdomain-specific language 领域特
定语言)。这个被称为 Query DSL。

一. 基本数据格式

举个栗子🌰

GET movies/_search
{
  "query": {
    "bool": {
      "filter": [
        {
          "terms": {
            "title": [
              "beautiful"
            ]
          }
        },
        {
          "range": {
            "year": {
              "gte": 1990,
              "lte": 1992
            }
          }
        }
      ]
    }
  }
}
//------------------------结果-----------------------------------
{
  "took" : 38,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 0.0,
    "hits" : [
      {
        "_index" : "movies",
        "_type" : "_doc",
        "_id" : "130996",
        "_score" : 0.0,
        "_source" : {   // _source: 需要返回的字段
          "id" : "130996",
          "year" : 1992,
          "@version" : "1",
          "title" : "The Beautiful Story",
          "genre" : [
            "Adventure",
            "Drama",
            "Fantasy"
          ]
        }
      }
    ]
  }
}

二. match (匹配查询)

  1. 对于数据类型的(非字符串), 进行精确匹配
# 找出2012年播放的电影
GET movies/_search
{
  "query": {
    "match": {
      "year": 2012
    }
  }
}
  1. 对于字符串类型的字段, 进行全文搜索, 模糊匹配
# 找出标题含有beautiful的电影
GET movies/_search
{
  "query": {
    "match": {
      "title": "beautiful"
    }
  }
}
  1. 字符串,多个单词 (分词+全文检索)
# 找出标题含有beautiful mind的电影
GET movies/_search
{
  "query": {
    "match": {
      "title": "beautiful mind"  // 包含beautiful 或 mind 或 beautiful mind 的
    }
  }
}
  1. 精确匹配字符串
# 精确匹配字符串
GET movies/_search
{
  "query": {
    "match": {
      "title.keyword": "beautiful mind"  
    }
  }
}

三. match_phrase(短语匹配)

将需要匹配的值当成一个整体单词(不分词)进行检索

# 将需要匹配的值当成一个整体单词(不分词)进行检索
GET movies/_search
{
  "query": {
    "match_phrase": {
      "title": "beautiful mind"  
    }
  }
}

四. multi_match(多字段匹配)

# 多字段匹配
GET movies/_search
{
  "query": {
    "multi_match": {
      "query": "beautiful 2010",
      "fields": ["title","year"] 
    }
  }
}

五. bool(复合查询)

bool 用来做复合查询: 复合语句可以合并任何其它查询语句,包括复合语句,复合语句之间可以互相嵌套,可以表达非常复杂的逻辑

  1. must: 必须达到must所列举的所有条件
GET movies/_search
{
  "query": {
    "bool": {
      "must": [
        {               
          "range": {
            "year": {
              "gte": 1990,
              "lte": 1992
            }
          }
        }, //条件1   年份范围内
        {
          "match": {
            "title": "beautiful mind"
          }
        }   // 条件2  标题包含关键词
      ]
    }
  }
}
  1. must_not 必须不是指定的情况
GET movies/_search
{
  "size": 1, 
  "query": {
    "bool": {
      "must_not": [
        {
          "range": {
            "year": {
              "gte": 1990,
              "lte": 1992
            }
          }
        },
        {
          "match": {
            "title": "beautiful mind"
          }
        }
      ]
    }
  }
}
  1. should 应该达到的条件- (匹配到能提高文档得分, 匹配不到不会影响查询结果)
GET movies/_search
{
  "size": 1, 
  "query": {
    "bool": {
      "must": [
        {
          "range": {
            "year": {
              "gte": 1990,
              "lte": 1992
            }
          }
        },
        {
          "match": {
            "title": "beautiful"
          }
        }
      ],
      "should": [
        {
          "match": {
            "title": "mind"
          }
        }
      ]
    }
  }
}
  1. filter (结果过滤) 为了不计算分数 Elasticsearch 会自动检查场景并且优化查询的执行。
GET movies/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "title": "beautiful"
          }
        }
      ],
      "filter": [
        {
          "range": {
            "year": {
              "gte": 2010,
              "lte": 2012
            }
          }
        }
      ]
    }
  }
}

六. term(精确匹配)

全文检索字段用 match,其他非 text 字段匹配用 term

举个栗子🌰

GET movies/_search
{
  "query": {
    "term": {
      "year": "2010"
    }
  }
}

七. aggs(聚合)

创建employee 索引 并准备数据

// 创建索引
PUT employee
{
  "mappings": {
    "properties": {
      "id":{
        "type": "integer"
      },
      "name":{
        "type": "keyword"
      },
      "job":{
        "type": "keyword"
      },
      "age":{
        "type": "integer"
      },
      "gender":{
        "type": "keyword"
      }
    }
  }
}

// 准备数据
PUT employee/_bulk
{"index": {"_id": 1}}
{"id": 1, "name": "Bob", "job": "java", "age": 21, "sal": 8000, "gender": "female"}
{"index": {"_id": 2}}
{"id": 2, "name": "Rod", "job": "html", "age": 31, "sal": 18000, "gender": "female"}
{"index": {"_id": 3}}
{"id": 3, "name": "Gaving", "job": "java", "age": 24, "sal": 12000, "gender": "male"}
{"index": {"_id": 4}}
{"id": 4, "name": "King", "job": "dba", "age": 26, "sal": 15000, "gender": "female"}
{"index": {"_id": 5}}
{"id": 5, "name": "Jonhson", "job": "dba", "age": 29, "sal": 16000, "gender": "male"}
{"index": {"_id": 6}}
{"id": 6, "name": "Douge", "job": "java", "age": 41, "sal": 20000, "gender": "female"}
{"index": {"_id": 7}}
{"id": 7, "name": "cutting", "job": "dba", "age": 27, "sal": 7000, "gender": "male"}
{"index": {"_id": 8}}
{"id": 8, "name": "Bona", "job": "html", "age": 22, "sal": 14000, "gender": "female"}
{"index": {"_id": 9}}
{"id": 9, "name": "Shyon", "job": "dba", "age": 20, "sal": 19000, "gender": "female"}
{"index": {"_id": 10}}
{"id": 10, "name": "James", "job": "html", "age": 18, "sal": 22000, "gender": "male"}
{"index": {"_id": 11}}
{"id": 11, "name": "Golsling", "job": "java", "age": 32, "sal": 23000, "gender": "female"}
{"index": {"_id": 12}}
{"id": 12, "name": "Lily", "job": "java", "age": 24, "sal": 2000, "gender": "male"}
{"index": {"_id": 13}}
{"id": 13, "name": "Jack", "job": "html", "age": 23, "sal": 3000, "gender": "female"}
{"index": {"_id": 14}}
{"id": 14, "name": "Rose", "job": "java", "age": 36, "sal": 6000, "gender": "female"}
{"index": {"_id": 15}}
{"id": 15, "name": "Will", "job": "dba", "age": 38, "sal": 4500, "gender": "male"}
{"index": {"_id": 16}}
{"id": 16, "name": "smith", "job": "java", "age": 32, "sal": 23000, "gender": "male"}

单值: sum, avg, min, max, cardinality

  1. sum 求和
# 查询工资的总和
GET employee/_search
{
  "size": 0,
  "aggs": {
    "sum_sal": {
      "sum": {
        "field": "sal"
      }
    }
  }
}
  1. avg 平均
# 查询平均工资
GET employee/_search
{
  "size": 0,
  "aggs": {
    "avg_sal": {
      "avg": {
        "field": "sal"
      }
    }
  }
}
  1. min 最小值
# 查询最低工资
GET employee/_search
{
  "size": 0,
  "aggs": {
    "min_sal": {
      "min": {
        "field": "sal"
      }
    }
  }
}
  1. max 最大值
# 查询最高工资
GET employee/_search
{
  "size": 0,
  "aggs": {
    "max_sal": {
      "max": {
        "field": "sal"
      }
    }
  }
}
  1. cardinality (去重)
# 查询总共有多少个岗位(对属性去重后count查询)
GET employee/_search
{
  "size": 0,
  "aggs": {
    "sum_job": {
      "cardinality": {
        "field": "job"
      }
    }
  }
}

返回多值 : stats , terms

  1. stats
# 查询员工工资信息(数值类型)
GET employee/_search
{
  "size": 0, 
  "aggs": {
    "sal_info": {
      "stats": {
        "field": "sal"
      }
    }
  }
}
//----------------------------结果--------------------------------
{
  "took" : 9,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 16,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [ ]
  },
  "aggregations" : {
    "sal_info" : {
      "count" : 16,   
      "min" : 2000.0,
      "max" : 23000.0,
      "avg" : 13281.25,
      "sum" : 212500.0
    }
  }
}

  1. terms
# 查询每个岗位有多少人
GET employee/_search
{
  "size": 0,
  "aggs": {
    "job_emps_num": {
      "terms": {
        "field": "job"
      }
    }
  }
}

复杂聚合嵌套

举个栗子🌰

# 查询每个岗位下工资的信息(平均、最高、最少等)
GET employee/_search
{
  "size": 0, 
  "aggs": {
    "job_info": {
      "terms": {
        "field": "job"
      },
      "aggs": {
        "diff_job_sal_info": {
          "stats": {
            "field": "sal"
          }
        }
      }
    }
  }
}

# 查询不同工种的男女员工数量、然后统计不同工种下男女员工的工资信息
GET employee/_search
{
  "size": 0,
  "aggs": {
    "job_info": {
      "terms": {
        "field": "job"
      },
      "aggs": {
        "diff_job_gender_no": {
          "terms": {
            "field": "gender"
          },
          "aggs": {
            "diff_job_gender_sal_info": {
              "stats": {
                "field": "sal"
              }
            }
          }
        }
      }
    }
  }
}

# 查询年龄最大的两位员工的信息
GET employee/_search
{
  "size": 0,
  "aggs": {
    "older_two_emp": {
      "top_hits": {
        "size": 2,
        "sort": [
          {
            "age": {
              "order": "desc"
            }
          }
        ]
      }
    }
  }
}

# 查询不同工资区间员工工资的统计信息
GET employee/_search
{
  "size": 0,
  "aggs": {
    "rang_sal_info": {
      "range": {
        "field": "sal",
        "ranges": [
          {
            "key": "0 <= sal < 10001", 
            "to": 10001
          },
          {
            "key": "10001 <= sal < 20001", 
            "from": 10001, 
            "to": 20001
          },
          {
            "key": "20001 <= sal < 30001", 
            "from": 20001, 
            "to": 30001
          }
        ]
      }
    }
  }
}

# 以直方图的方式以每5000元为一个区间查询员工工资信息
GET employee/_search
{
  "size": 0,
  "aggs": {
    "range_sal_info": {
      "histogram": {
        "field": "sal",
        "interval": 5000,
        "extended_bounds": {
          "min": 0,
          "max": 15000
        }
      }
    }
  }
}

# 查询平均工资最低的工种
GET employee/_search
{
  "size": 0,
  "aggs": {
    "job_info": {
      "terms": {
        "field": "job"
      },
      "aggs": {
        "diff_job_avg_sal": {
          "avg": {
            "field": "sal"
          }
        }
      }
    },
    "min_avg_sal_job": {
      "min_bucket": {
        "buckets_path": "job_info>diff_job_avg_sal"
      }
    }
  }
}

# 查询年龄大于30岁的员工的平均工资
GET employee/_search
{
  "size": 0, 
  "query": {
    "range": {
      "age": {
        "gt": 30
      }
    }
  },
  "aggs": {
    "gt_30_emp_avg_sal": {
      "avg": {
        "field": "sal"
      }
    }
  }
}

# 查询Java员工的平均工资(不进行相关性算法,效率更高)
GET employee/_search
{
  "size": 0, 
  "query": {
    "constant_score": {
      "filter": {
        "term": {
          "job": "java"
        }
      },
      "boost": 1.2
    }
  },
  "aggs": {
    "java_emp_avg_sal": {
      "avg": {
        "field": "sal"
      }
    }
  }
}

# 求30岁以上的员工平均工资和所有员工的平均工资
GET employee/_search
{
  "size": 0,
  "aggs": {
    "all_emp_avg_sal": {
      "avg": {
        "field": "sal"
      }
    },
    "gt_30_emp_avg_info": {
      "filter": {
        "range": {
          "age": {
            "gt": 30
          }
        }
      },
      "aggs": {
        "gt_30_emp_avg_sal": {
          "avg": {
            "field": "sal"
          }
        }
      }
    }
  }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值