美文网首页
4.4-Query&Filtering实现多字符串多字段查询

4.4-Query&Filtering实现多字符串多字段查询

作者: 落日彼岸 | 来源:发表于2020-03-30 20:43 被阅读0次

Query Context & Filter Context

image.png
  • ⾼级搜索的功能:⽀持多项⽂本输⼊,针对多个字 段进⾏搜索。

  • 搜索引擎⼀般也提供基于时间,价格等条件的过滤

  • 在 ElasticSearch 中,有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 查询,则每个查询⼦句计算得出的评分会被合并到总的相关性评分中。

关键字 类型
must Query Context
必须匹配。 贡献算分
should Query Context
选择性匹配。贡献算分
must_not Filter Context
查询字句,必须不能匹配
filter Filter Context
必须匹配,但是不贡献算分

bool 查询语法

POST /products/_search
{
  "query": {
    "bool" : {
      "must" : {
        "term" : { "price" : "30" }
      },
      "filter": {
        "term" : { "avaliable" : "true" }
      },
      "must_not" : {
        "range" : {
          "price" : { "lte" : 10 }
        }
      },
      "should" : [
        { "term" : { "productID.keyword" : "JODL-X-1937-#pV7" } },
        { "term" : { "productID.keyword" : "XHDK-A-1293-#fJ3" } }
      ],
      "minimum_should_match" :1
    }
  }
}
  • ⼦查询可以任意顺序出现

  • 可以嵌套多个查询

  • 如果你的 bool 查询中,没有 must 条件, should 中必须⾄少满⾜⼀条查询

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

image.png image.png
  • 解决⽅案:增加⼀个 genre count 字段进 ⾏计数

增加 count 字段,使⽤ bool 查询解决

  • 增加 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}}}

      ]
    }
  }
}

#Filter。不参与算分,结果的score是0
POST /newmovies/_search
{
  "query": {
    "bool": {
      "filter": [
        {"term": {"genre.keyword": {"value": "Comedy"}}},
        {"term": {"genre_count": {"value": 1}}}
        ]

    }
  }
}

Filter Context – 不影响算分

#Filtering Context
POST _search
{
  "query": {
    "bool" : {

      "filter": {
        "term" : { "avaliable" : "true" }
      },
      "must_not" : {
        "range" : {
          "price" : { "lte" : 10 }
        }
      }
    }
  }
}

image.png

Query Context – 影响算分

POST /products/_search
{
  "query": {
    "bool": {
      "should": [
        {
          "term": {
            "productID.keyword": {
              "value": "JODL-X-1937-#pV7"}}
        },
        {"term": {"avaliable": {"value": true}}
        }
      ]
    }
  }
}
image.png

bool 嵌套

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

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

  • 同⼀层级下的竞争字段,具有有相同的权重

  • 通过嵌套 bool 查询,可以改变对算分的影响

POST /animals/_search
{
  "query": {
    "bool": {
      "should": [
        { "term": { "text": "brown" }},
        { "term": { "text": "red" }},
        { "term": { "text": "quick"   }},
        { "term": { "text": "dog"   }}
      ]
    }
  }
}

POST /animals/_search
{
  "query": {
    "bool": {
      "should": [
        { "term": { "text": "quick" }},
        { "term": { "text": "dog"   }},
        {
          "bool":{
            "should":[
               { "term": { "text": "brown" }},
                 { "term": { "text": "brown" }},
            ]
          }

        }
      ]
    }
  }
}

控制字段的 Boosting

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" }


POST blogs/_search
{
  "query": {
    "bool": {
      "should": [
        {"match": {
          "title": {
            "query": "apple,ipad",
            "boost": 1.1
          }
        }},

        {"match": {
          "content": {
            "query": "apple,ipad",
            "boost": 1
          }
        }}
      ]
    }
  }
}
  • Boosting 是控制相关度的⼀种⼿段

    • 索引,字段 或查询⼦条件
  • 参数 boost的含义

    • 当 boost > 1 时,打分的相关度相对性提升

    • 当 0 < boost < 1 时,打分的权重相对性降低

    • 当 boost < 0 时,贡献负分

Not Quite Not

  • 要求苹果公司的产品信息优先
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" }


POST news/_search
{
  "query": {
    "bool": {
      "must": {
        "match":{"content":"apple"}
      }
    }
  }
}
image.png

Boosting Query

POST news/_search
{
  "query": {
    "bool": {
      "must": {
        "match":{"content":"apple"}
      },
      "must_not": {
        "match":{"content":"pie"}
      }
    }
  }
}

POST news/_search
{
  "query": {
    "boosting": {
      "positive": {
        "match": {
          "content": "apple"
        }
      },
      "negative": {
        "match": {
          "content": "pie"
        }
      },
      "negative_boost": 0.5
    }
  }
}

本节知识点回顾

  • Query Context vs. Filter Context

  • Bool Query – 更多的条件组合

  • 查询结构与相关性算分

  • 如何控制查询的精确度

    • Boosting & Boosting Query

课程demo

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" }



#基本语法
POST /products/_search
{
  "query": {
    "bool" : {
      "must" : {
        "term" : { "price" : "30" }
      },
      "filter": {
        "term" : { "avaliable" : "true" }
      },
      "must_not" : {
        "range" : {
          "price" : { "lte" : 10 }
        }
      },
      "should" : [
        { "term" : { "productID.keyword" : "JODL-X-1937-#pV7" } },
        { "term" : { "productID.keyword" : "XHDK-A-1293-#fJ3" } }
      ],
      "minimum_should_match" :1
    }
  }
}

#改变数据模型,增加字段。解决数组包含而不是精确匹配的问题
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}}}

      ]
    }
  }
}

#Filter。不参与算分,结果的score是0
POST /newmovies/_search
{
  "query": {
    "bool": {
      "filter": [
        {"term": {"genre.keyword": {"value": "Comedy"}}},
        {"term": {"genre_count": {"value": 1}}}
        ]

    }
  }
}


#Filtering Context
POST _search
{
  "query": {
    "bool" : {

      "filter": {
        "term" : { "avaliable" : "true" }
      },
      "must_not" : {
        "range" : {
          "price" : { "lte" : 10 }
        }
      }
    }
  }
}


#Query Context
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" }


POST /products/_search
{
  "query": {
    "bool": {
      "should": [
        {
          "term": {
            "productID.keyword": {
              "value": "JODL-X-1937-#pV7"}}
        },
        {"term": {"avaliable": {"value": true}}
        }
      ]
    }
  }
}


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


#Controll the Precision
POST _search
{
  "query": {
    "bool" : {
      "must" : {
        "term" : { "price" : "30" }
      },
      "filter": {
        "term" : { "avaliable" : "true" }
      },
      "must_not" : {
        "range" : {
          "price" : { "lte" : 10 }
        }
      },
      "should" : [
        { "term" : { "productID.keyword" : "JODL-X-1937-#pV7" } },
        { "term" : { "productID.keyword" : "XHDK-A-1293-#fJ3" } }
      ],
      "minimum_should_match" :2
    }
  }
}



POST /animals/_search
{
  "query": {
    "bool": {
      "should": [
        { "term": { "text": "brown" }},
        { "term": { "text": "red" }},
        { "term": { "text": "quick"   }},
        { "term": { "text": "dog"   }}
      ]
    }
  }
}

POST /animals/_search
{
  "query": {
    "bool": {
      "should": [
        { "term": { "text": "quick" }},
        { "term": { "text": "dog"   }},
        {
          "bool":{
            "should":[
               { "term": { "text": "brown" }},
                 { "term": { "text": "brown" }},
            ]
          }

        }
      ]
    }
  }
}


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" }


POST blogs/_search
{
  "query": {
    "bool": {
      "should": [
        {"match": {
          "title": {
            "query": "apple,ipad",
            "boost": 1.1
          }
        }},

        {"match": {
          "content": {
            "query": "apple,ipad",
            "boost":
          }
        }}
      ]
    }
  }
}

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" }


POST news/_search
{
  "query": {
    "bool": {
      "must": {
        "match":{"content":"apple"}
      }
    }
  }
}

POST news/_search
{
  "query": {
    "bool": {
      "must": {
        "match":{"content":"apple"}
      },
      "must_not": {
        "match":{"content":"pie"}
      }
    }
  }
}

POST news/_search
{
  "query": {
    "boosting": {
      "positive": {
        "match": {
          "content": "apple"
        }
      },
      "negative": {
        "match": {
          "content": "pie"
        }
      },
      "negative_boost": 0.5
    }
  }
}

相关阅读

相关文章

  • 4.4-Query&Filtering实现多字符串多字段查询

    Query Context & Filter Context ⾼级搜索的功能:⽀持多项⽂本输⼊,针对多个字 段进⾏...

  • SSO混合互联认证说明

    多租户互联方案(已实现) 通过查询用户的sql决定,如果查到的用户包含e_code字段,则根据e_code字段查找...

  • 20220722总结

    多对多查询,出现重复,影响分页,建议同张表创建字段 1.针对单表版本限制方案 使用单表添加字段,添加是否开启ios...

  • 07-mongodb操作实例

    查询 1.多条件查询Article 查询Article中title字段中含有字符串“哈哈”,或者tags中含有“哈...

  • Solr6.5查询参数说明(四)

    1、常用 q-查询字符串,这个是必须的。如果查询所有*:*,根据指定字段查询(Name:张三 AND Addre...

  • MySQL优化总结

    建表原则 定长字段与变长字段分离,使存储空间整齐,加速查询; 常用字段与不常用字段分离 适当增加冗余字段,如一对多...

  • 数据库学习笔记-基础查询

    基础查询 查询字段语法 查询单字段SELECT 字段 FROM 表名;查询多字段SELECT 字段1,字段2,字段...

  • django-blog:多对多查询

    简单写一下多对多查询model 不是多对多的字段我就没写上来的 在编写view时 我需要 查出 某一篇文章 ...

  • 小程序模糊查询

    小程序云开发模糊查询,实现数据库字段的模糊搜索 查询goods表中 字段为goodsname中 like='土豆'...

  • mybatis高级映射多对多查询实现

    1.同以前一样,首先给一个使用多对多的需求, 要查询用户以及用户所购买的商品信息,经过分析用户和商品数据库级别没有...

网友评论

      本文标题:4.4-Query&Filtering实现多字符串多字段查询

      本文链接:https://www.haomeiwen.com/subject/arlbuhtx.html