企业项目管理、ORK、研发管理与敏捷开发工具平台

网站首页 > 精选文章 正文

Elasticsearch 查询语句Query DSL语句之单个条件查询

wudianyun 2024-12-25 12:18:34 精选文章 53 ℃

Elasticsearch的查询语句Query DSL是掌握搜索技能的基石,下图来概括一下单个条件查询语句的主要使用:

elasticsearch单个条件查询

一.精准查询

1.exists

  • 功能: 判断某个字段是否在文档中存在
  • 用法:
    • 参数: field -> 指定要判断的字段名称
  • 实例:
PUT test_steam_item_730 
{
  "aliases": {
    "steam_item": {}
  },
  "mappings": {
    "dynamic":false,
    "properties": {
      "id":{
        "type":"long"
      },
      "app_id":{
        "type":"integer"
      },
      "image_url":{
        "type":"keyword",
        "index":false
      },
      "name":{
        "type":"text"
      },
      "min_price":{
        "type":"double"
      },
      "attribute":{
        "properties": {
          "type":{
            "type":"keyword"
          },
          "rarity":{
            "type":"keyword"
          }
        }
      },
      "extra_tag_ids":{
        "type":"keyword"
      }
    }
  },
  "settings": {
    "number_of_shards": 1,
    "number_of_replicas": 0
  }
}

插入一些值

POST _bulk
{"index":{"_index":"test_steam_item_730","_id":1}}
{"id":1,"name":"第一个饰品","image_url":"test1.png","extra_tag_ids":[],"attribute":{"type":"csgo_type_knife","rarity":"normal"}}
{"index":{"_index":"test_steam_item_730","_id":2}}
{"id":2,"name":"","extra_tag_ids":[null],"attribute":{"type":"csgo_type_knife"},"min_price":0}

使用exists来判断某个字段值是否存在

GET test_steam_item_730/_doc/_search
{
  "query": {
    "bool": {
      "must_not": [
        {
          "exists": {
            "field": "extra_tag_ids"
          }
        }
      ]
    }
  }
}
  • 笔者有话说:
    • 以下情况会认为字段是不存在的
      • 字段值为null,数组类型字段值为[]
      • 字段指定了index=false的和doc_values=false的字段
      • 字段的值的长度超过了指定的ignore_above的长度
    • 以下情况认为字段是存在的
      • 空字符串,即""
      • 数据有非null的元素值
      • 自定义的null值,在mapping中定义的null_value,如"NULL"

2.ids

  • 功能: 通过文档ID批量查询(文档ID即文档的_id)
  • 用法:
    • 参数: values -> 文档ID列表
  • 实例:
GET test_steam_item_730/_doc/_search
{
  "query":{
    "ids":{
      "values":[1,2]
    }
  }
}

3.range

  • 功能:根据大小范围查找(类似于关系型数据库中的between and)
  • 参数:
    • gt: 大于指定值
    • gte: 大于等于指定值
    • lt: 小于指定值
    • lte: 小于等于指定值
    • format: 格式(一般是Date类型的格式化模式)
    • boost: 指定权重
  • 实例:
GET test_steam_item_730/_doc/_search
{
  "query":{
    "range":{
      "min_price":{
        "gte":0.1,
        "lte":150
      }
    }
  }
}

查询min_price字段值在[0.1,150]这个范围的数据

4.term

  • 功能: 查询等于某个值的文档
  • 参数:
    • 字段名 : 条件值
  • 实例:
GET test_steam_item_730/_doc/_search
{
  "query":{
    "term":{
      "app_id":730
    }
  }
}

查询 app_id = 730 的数据

5.terms

  • 功能: 查询字段在某个值列表范围内
  • 参数:
    • 字段名 : [字段值列表]
  • 实例:
POST test_steam_item_730/_bulk
{"update":{"_index":"test_steam_item_730","_id":1}}
{"doc":{"extra_tag_ids":["热门","热销","推荐"]}}
{"update":{"_index":"test_steam_item_730","_id":2}}
{"doc":{"extra_tag_ids":["热门","刀具"]}}

查询:

GET test_steam_item_730/_doc/_search
{
  "query":{
    "terms":{
      "extra_tag_ids":["热门","热销"]
    }
  }
}

这个查询语句会查出包含热门或热销这两个标签中任意一个标签的文档

  • 如果想查出包含这两个标签的文档呢?
GET test_steam_item_730/_doc/_search
{
  "query": {
    "bool": {
      "filter": [
        {
          "term": {
            "extra_tag_ids": "热门"
          }
        },
        {
          "term": {
            "extra_tag_ids": "热销"
          }
        }
      ]
    }
  }
}

将它们当作并列条件即可

6.terms_set

  • 功能:和terms功能类似,但
  • 参数:
    • terms: 查询条件
    • minimum_should_match_field: 最小匹配的字段名称(该字段值必须是个数字类型)
  • 实例:

新增字段:

PUT test_steam_item_730/_mappings
{
  "properties":{
    "min_tag_count":{
      "type":"integer"
    }
  }
}

批量给最新字段添加值

POST test_steam_item_730/_bulk
{"update":{"_index":"test_steam_item_730","_id":1}}
{"doc":{"extra_tag_ids":["热门","热销","推荐"],"min_tag_count":2}}
{"update":{"_index":"test_steam_item_730","_id":2}}
{"doc":{"extra_tag_ids":["热门","刀具"],"min_tag_count":2}}

查询:

GET test_steam_item_730/_doc/_search
{
  "query": {
    "terms_set": {
      "extra_tag_ids": {
        "terms": [
          "热门",
          "热销"
        ],
        "minimum_should_match_field": "min_tag_count"
      }
    }
  }
}

查询出包含 热门 和 热销 这两个标签,而且min_tag_count要和查询的标签数量一致(即为2)

二.模糊匹配

1.fuzzy

  • 功能: 相似值匹配
  • 参数:
    • value: 要查询的值
    • max_expansions: 最大匹配长度
    • fuzziness :最大编辑距离(是指两个字串之间,由一个转成另一个所需的最少编辑操作次数),默认为 AUTO
    • prefix_length: 最大前缀匹配长度
    • transpositions : 是否支持模糊转置( ik -> ki )
  • 实例:
GET test_steam_item_730/_doc/_search
{
  "query":{
    "fuzzy":{
      "name":{
        "value":"龙王"
      }
    }
  }
}


2.prefix

  • 功能: 前缀匹配
  • 参数:
    • value: 目标值
    • rewrite: 是否允许重写查询
    • case_insensitive: 是否不区分大小写
  • 实例:
GET test_steam_item_730/_doc/_search
{
  "query":{
    "prefix":{
      "name":{
        "value":"久经沙场"
      }
    }
  }
}

只要包含这个查询的值就可以

3.wildcard

  • 功能: 通配符匹配
  • 参数:
    • value: 匹配的表达式值(含通配符)
      • ? : 匹配单个
      • * : 匹配0个、1个或多个
    • case_insensitive: 是否不区分大小写
  • 注意:尽量不要在以*或?作为匹配表达式的开头(影响性能)
  • 实例:
GET test_steam_item_730/_doc/_search
{
  "query":{
    "wildcard":{
      "name":{
        "value":"久经**"
      }
    }
  }
}

4.regexp

  • 功能: 正则表达式匹配(与wildcard差不多,不过功能更强大)
  • 参数:
    • value: 正则表达式
    • case_insensitive: 是否不区分大小写
  • 注: 实际工具中很少使用(因为性能比较低)

5.全文检索

(1)match

  • 功能:匹配查询的词组(会对查询的目标内容进行分词)
  • 参数:
    • query: 查询的目标内容
    • analyzer: 指定分词器
    • operator:操作符
      • OR : 满足其中一个词即可
      • AND : 满足所有的词才算匹配成功
    • minimum_should_match: 最小匹配数量
  • 实例:
GET test_steam_item_730/_doc/_search
{
  "query":{
    "match":{
      "name":{
        "query":"久经沙场"
      }
    }
  }
}

(2)match_phrase

  • 功能:短语匹配(必须包含整个短语才会匹配成功,把查询的内容当作一个整体,只有完全包含这个内容才算匹配成功)
  • 参数:
    • query: 查询的目标内容
    • analyzer: 指定分词器
GET test_steam_item_730/_doc/_search
{
  "query":{
    "match_phrase":{
      "name":{
        "query":"略有磨损"
      }
    }
  }
}

必须包括 "略有磨损" 这个词才算匹配

(3)match_phrase_prefix

  • 功能:短语前缀匹配
  • 参数:
    • query: 查询的目标内容
    • analyzer: 指定分词器
GET test_steam_item_730/_doc/_search
{
  "query":{
    "match_phrase_prefix":{
      "name":{
        "query":"略有磨损"
      }
    }
  }
}

个人理解和match_phrase 区别不大

(5)multi_match

  • 功能: 多字段匹配
  • 参数:
    • query: 查询的内容
    • fields: 匹配的字段列表
GET test_steam_item_730/_doc/_search
{
  "query":{
    "multi_match":{
      "query":"略有磨损",
      "fields":["name","short_name"]
    }
  }
}

name和short_name这两个字段匹配略有磨损



Tags:

最近发表
标签列表