Elasticsearch核心技术与实战学习笔记 第四章 27 | Query&Filtering与多字符串多字段查询

一 序

   本文属于极客时间Elasticsearch核心技术与实战学习笔记系列。

二 Query Context & Filter Context

  高级搜索的功能,支持多想文本输入,针对多个字段进行搜索
搜索引擎一般也提供时间,价格等条件过滤
在 ES 中,有 Query 和 Filter 两种 Context
Query Context :相关性算分
Filter Context :不需要算分(YES OR NO), 可以利用 Cache 获得更好的性能

条件组合

假设搜索一本电影

  • 评论中包含了 Guitar ,用户打分高于 3 分,同时上映时间在 1993 到 2000 年之间

这个搜索包含了 3 段逻辑,针对不同的字段

  • 评论字段中要包含 Guitar 、用户评论大于 3、上映时间日期在给定范围内

同时包含这三个逻辑,并且有比较好的性能

  • 复合查询: bool Query

bool 查询

 

一个 bool 查询,是一个或者多个查询子句的组合

  • 总共包含 4 种子句,其中 2 种会影响算分,2 种不影响算分

相关性并不只是全文本搜索的专利。也适合 yes | no 的子句,匹配的子句越多,相关性评分越高。如果多条查询子句被合并为一条复合查询语句,比如 bool 查询,则每个查询子句计算得出的评分会被合并到总的相关性评分中。

bool 查询语句

  • 子查询可以任意顺序出现
  • 可以嵌套多个查询
  • 如果你的 bool 查询中,没有 must 条件,should 中必须满足一条查询

准备数据

POST /products/_bulk
{ "index": { "_id": 1 }}
{ "price" : 10,"avaliable":true,"date":"2018-01-01", "productID" : "XHDK-A-1293-#fJ3" }
{ "index": { "_id": 2 }}
{ "price" : 20,"avaliable":true,"date":"2019-01-01", "productID" : "KDKE-B-9947-#kL5" }
{ "index": { "_id": 3 }}
{ "price" : 30,"avaliable":true, "productID" : "JODL-X-1937-#pV7" }
{ "index": { "_id": 4 }}
{ "price" : 30,"avaliable":false, "productID" : "QQPX-R-3956-#aD8" }

这是一个bool搜索的例子,条件:价格是30.filter对算分无影响,对应的条件是true.must_not 对算分无影响。should的条件id满足两个之一。

如何解决结构化查询 -“包含而不是相等” 的问题

增加 count 字段,使用 bool 查询

#改变数据模型,增加字段。解决数组包含而不是精确匹配的问题
POST /newmovies/_bulk
{ "index": { "_id": 1 }}
{ "title" : "Father of the Bridge Part II","year":1995, "genre":"Comedy","genre_count":1 }
{ "index": { "_id": 2 }}
{ "title" : "Dave","year":1993,"genre":["Comedy","Romance"],"genre_count":2 }
#must,有算分
POST /newmovies/_search
{
  "query": {
    "bool": {
      "must": [
        {"term": {"genre.keyword": {"value": "Comedy"}}},
        {"term": {"genre_count": {"value": 1}}}

      ]
    }
  }
}

must 有算分 

Filter。不参与算分,结果的score是0 

should  影响算分:对比前面可见这个分数高了。

bool 嵌套

#嵌套,实现了 should not 逻辑
POST /products/_search
{
  "query": {
    "bool": {
      "must": {
        "term": {
          "price": "30"
        }
      },
      "should": [
        {
          "bool": {
            "must_not": {
              "term": {
                "avaliable": "false"
              }
            }
          }
        }
      ],
      "minimum_should_match": 1
    }
  }
}

查询语句的结构,会对相关度算分产生影响

  • 同一层级下的竞争字段,具有相同的权重
  • 通过嵌套 bool 查询,可以改变对算分的影响

上面例子,左侧相同的权重,对比下右侧的,我们吧颜色该写到子查询,会影响到算分。

控制字段的 Boosting

demo:

DELETE blogs
POST /blogs/_bulk
{ "index": { "_id": 1 }}
{"title":"Apple iPad", "content":"Apple iPad,Apple iPad" }
{ "index": { "_id": 2 }}
{"title":"Apple iPad,Apple iPad", "content":"Apple iPad" }

1 先调整title的boost,返回对应2再前面 

如果调整body的boost: 文档1会在前面

demo2:搜索新闻的例子

DELETE news
POST /news/_bulk
{ "index": { "_id": 1 }}
{ "content":"Apple Mac" }
{ "index": { "_id": 2 }}
{ "content":"Apple iPad" }
{ "index": { "_id": 3 }}
{ "content":"Apple employee like Apple Pie and Apple Juice" }

插入3条数据,要求搜索苹果公司的产品优先。

默认条件的搜索,不是符合预期。

加入must_not做过滤。返回2条。

通过调整boost,返回顺序也做了调整。 

 小结

  • Query Context vs Filter Context
  • Bool Query - 更多的条件组合
  • 查询结构与相关性算分
  • 如何控制查询的精确度
    • Boosting & Boosting Query

猜你喜欢

转载自blog.csdn.net/bohu83/article/details/106433161