ElasticSearch系列二 DSL查询

查询和过滤

叶查询子句:在特定的字段上查找特定的值,比如 match term rang 可以理解为单条件查询

复合查询字句:包含其他叶查询或复合查询,可以理解为多条件查询.

查询: query 用于检索内容与条件是否匹配,并计算_score份数

过滤:filter不计算匹配得分,只是简单的决定文档是否匹配,主要用于过滤结构化数据 如时间 状态 类型等字段

简单查询

我们索引数据的结构

{
        "_index": "meadin",
        "_type": "industry_news",
        "_id": "Ly93d3cudHJhdmVsZGFpbHkuY24vYXJ0aWNsZS8xMzcwNzQ=",
        "_score": 16.389927,
        "_source": {
          "id": "Ly93d3cudHJhdmVsZGFpbHkuY24vYXJ0aWNsZS8xMzcwNzQ=",
          "title": "美团发布全国首个《在线平台酒店预售服务规范》标准",
          "synopsis": "4月13日,美团发布业内首个《在线平台酒店预售服务规范》(以下简称标准),从预售服务要求、流程、监督和评价...",
          "source": "环球旅讯",
          "newsUrl": "https://www.traveldaily.cn/article/137074",
          "newsIssueTime": "2020-04-14T06:56:45+0800",
          "createDate": "2020-04-13",
          "context": """
			<p>4月13日,美团发布业内首个《在线平台酒店预售服务规范》(以下简称标准),从预售服务要求、流程
          "dateSource": 112
        }
GET /meadin/industry_news/_search
{
  "query": {
    "bool": {
      "must": [
        {"match": {"title": "酒店" }},
        {"match": {"context": "洲际"}}       
      ],
    "filter": {
      "range": {
        "newsIssueTime": {
          "gte":"2020-03-01T21:51:04Z",
          "lte": "2020-05-01T21:51:04Z"
        }
      }
    }
   }
  }
}

相当于sql语句 
select * from industry_news where title like %酒店% and content like %洲际% and newsIssueTime between '' and '' 

match

查询默认是分词的 {“match”: {“title”: “酒店” }} 和 {“match”: {“title”: “酒店这里是被分词的” }}第二个条件比第一个条件查询到的结果只会多不会少,{“match”: {“title”: “酒店这里是被分词的” }} 可以理解为
{“match”: {“title”: “酒店” }} {“match”: {“title”: “这里” }} {“match”: {“title”: “分词” }} 三个条件查到 的结果的总和
lucece倒排索引
在这里插入图片描述
根据关键字找到所在的索引的ID 酒店 ->1 酒店这里是被分词的->1,2,4
match的模糊查询


GET /meadin/industry_news/_search
{
  "query": {
    "match": {
      "newsUrl": {
        "query": "article 137074",
        "fuzziness": 1,
        "operator": "and"
        
      }
    }
  }
}

fuzziness参数的表示最大的编辑距离 默认是2
ac abc 编辑差一个字符
ad abcd 编辑差2个字符
编辑距离越小则两个字符串越像 我们使用fuzziness 一般都是设置为1
fuzzy 的模糊查询

GET /meadin/industry_news/_search
{
  "query": {
    "fuzzy": {
      "source.keyword": "环球讯"
    }
  }
}

fuzzy 的模糊查询和term查询有点像 也是不分词的查询 fuzzy虽然不分词可以模糊匹配
环球讯 -> “source”: “环球旅讯” 可以匹配到这个, 但是如果是term查询就匹配不到了

match短语查询 match_parse

GET /meadin/industry_news/_search
{
  "query": {
    "match_phrase": {
      "title": "目前公司业务覆盖全国"
    }
  }
}

match_parse被查询的词"目前公司业务覆盖全国" 不会被分词,es拿着整个句子去索引里面匹配
“title”: “达实智能:目前公司业务覆盖全国” 这条消息是可以匹配到的.title字段在存储的时候会被分词,在倒排序索引中会有"目前公司业务覆盖全国" 所以可以查得到
如果把这里的match_phrase 改成term 是查不到的
如果这里把title 改成title.keyword也是查不到的
所以可以证明 “目前公司业务覆盖全国” 是title字段在倒排索引中的一个关键词

match 前缀查询
匹配以专家开头的标题的文章

GET /meadin/industry_news/_search
{
"query": {
  "match_phrase_prefix": {
    "title": "专家"
  }
}
}

macth多字段查询

GET /meadin/industry_news/_search
{
"query": {
 "multi_match": {
   "query": "资本",
   "type": "best_fields", 
   "fields": ["title^3","synopsis","context"]
  }
 }
}

在title synopisi contect 三个字段中查询 任意一个满足条件都会返回,title^3 计算份数的时候title字段的重要性是其他字段的三倍,多匹配查询内部的执行方式 根据 type 类型
默认就是best_fields:查找匹配任何字段的文章,但是使用最佳匹配字段的score
most_fields:查找匹配任何字段的文档,接合每个字段的score
cross_fields:用相同的分析器处理字段,把这些字段当做一个大的字段.
phrase:每个字段上运行短语匹配查询,接合每个字段的score
phrase_prefix:在每个字段是上运行短语前缀查询,结合每个字段的score

trem 查询(字段查询)

精准的查询,对查询结果不做相关性排序.常用语结构化数据 如 数字 日期 枚举
单个字段查询
select * from table where type=1

GET /meadin/industry_news/_search
{
"query": {
 "term": {
   "dateSource": 79
 }
 }
}

多字段查询
select * from table where type in (19,20,79)

GET /meadin/industry_news/_search
{
"query": {
 "terms": {
   "dateSource": [19,20,79]
 }
 }
}

范围查询

GET /meadin/industry_news/_search
{
"query": {
  "range": {
    "dateSource": {
      "gte": 10,
      "lte": 20
    }
  }
}
}

复合查询

复合查询就是将多个叶子查询组合到一起,组合方式有多种
must 必须出现在匹配的文档中 并且会影响匹配得分
filter 必须出现在匹配的文当中 不影响匹配得分
should 应该出现在匹配的文档中 匹配一个或多个should里面的条件(可以通过minimum_should_match参数设置 默认最少匹配一个)
must_not 必须不出现在匹配的文档中


GET /meadin/industry_news/_search
{
"query": {
  "bool": {
    "should": [
      {
        "constant_score": {
          "filter": {
          "term": {
            "context": "洗浴"
          }
          },
          "boost": 1.2
        }
      },
       {
        "constant_score": {
          "filter": {
          "term": {
            "context": "电视"
          }
          },
          "boost": 1.2
        }
      }
    ]
  }
}
}

查询context字段包含洗浴 或者 电视 的文档 constant_score 表示不计算词频 同一个词出现一次和出现多次得分是一样的,这样的查询场景 我们关心的是包含的要查询的内容多不多.好比 查找一家酒店 要求这个酒店 有 洗浴 电视 wifi 等 出现的项目越多排名越靠前

查询的优化

filter

GET meadin/industry_news/_search
{
  "query": {
    "bool": {
      "must": {
        "match": {
          "text": "quick brown fox"
        }
      },
      "filter": {
        "term": {
          "status": "1"
        }
      }
    }
  }
}
  1. 为每一个倒排索引构建一个 bitset(用来做缓存的二进制数组) 如下图
    在这里插入图片描述
  2. 根据查询条件 “status”: “1” 找到对应的 bitset [1,0,1] 通过bitset找到对应的数据doc1 和 doc3把数据返回给客户端
  3. cache bitset 跟踪query 在最近的256个query中超过一定次数使用的bitset会被缓存起来,以备下次使用
  4. bitset的查询是在query查询开始的时候 进行的,这样可以过滤掉大部分内容
  5. 以后只要有相同的filter 就会直接定位到相应的bitset

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值