• ElasticSearch7.3学习(二十一)----Filter与Query对比、使用explain关键字分析语法


    1、数据准备

    首先创建book索引

    1. PUT /book/
    2. {
    3. "settings": {
    4. "number_of_shards": 1,
    5. "number_of_replicas": 0
    6. },
    7. "mappings": {
    8. "properties": {
    9. "name": {
    10. "type": "text",
    11. "analyzer": "ik_max_word",
    12. "search_analyzer": "ik_smart"
    13. },
    14. "description": {
    15. "type": "text",
    16. "analyzer": "ik_max_word",
    17. "search_analyzer": "ik_smart"
    18. },
    19. "studymodel": {
    20. "type": "keyword"
    21. },
    22. "price": {
    23. "type": "double"
    24. },
    25. "timestamp": {
    26. "type": "date",
    27. "format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
    28. },
    29. "pic": {
    30. "type": "text",
    31. "index": false
    32. }
    33. }
    34. }
    35. }

    插入数据

    1. PUT /book/_doc/1
    2. {
    3. "name": "Bootstrap开发",
    4. "description": "Bootstrap是一个非常流行的开发框架。此开发框架可以帮助不擅长css页面开发的程序人员轻松的实现一个css,不受浏览器限制的精美界面css效果。",
    5. "studymodel": "201002",
    6. "price": 38.6,
    7. "timestamp": "2019-08-25 19:11:35",
    8. "pic": "group1/M00/00/00/wKhlQFs6RCeAY0pHAAJx5ZjNDEM428.jpg",
    9. "tags": [
    10. "bootstrap",
    11. "dev"
    12. ]
    13. }
    14. PUT /book/_doc/2
    15. {
    16. "name": "java编程思想",
    17. "description": "java语言是世界第一编程语言,在软件开发领域使用人数最多。",
    18. "studymodel": "201001",
    19. "price": 68.6,
    20. "timestamp": "2019-08-25 19:11:35",
    21. "pic": "group1/M00/00/00/wKhlQFs6RCeAY0pHAAJx5ZjNDEM428.jpg",
    22. "tags": [
    23. "java",
    24. "dev"
    25. ]
    26. }
    27. PUT /book/_doc/3
    28. {
    29. "name": "spring开发基础",
    30. "description": "spring 在java领域非常流行,java程序员都在用。",
    31. "studymodel": "201001",
    32. "price": 88.6,
    33. "timestamp": "2019-08-24 19:11:35",
    34. "pic": "group1/M00/00/00/wKhlQFs6RCeAY0pHAAJx5ZjNDEM428.jpg",
    35. "tags": [
    36. "spring",
    37. "java"
    38. ]
    39. }

    2、Filter与Query示例

    需求:用户查询description中有"java程序员",并且价格大于80小于90的数据。

    2.1 Query

    首先采用Query来进行查询,首先查询description中有"java程序员"。

    1. GET /book/_search
    2. {
    3. "query": {
    4. "bool": {
    5. "must": [
    6. {
    7. "match": {
    8. "description": "java程序员"
    9. }
    10. }
    11. ]
    12. }
    13. }
    14. }

    查询结果如下:

    可以看到,查询出来两条数据,score分别是1.9、0.5。

    然后查询description中有"java程序员",并且价格大于80小于90的数据

    1. GET /book/_search
    2. {
    3. "query": {
    4. "bool": {
    5. "must": [
    6. {
    7. "match": {
    8. "description": "java程序员"
    9. }
    10. },
    11. {
    12. "range": {
    13. "price": {
    14. "gte": 80,
    15. "lte": 90
    16. }
    17. }
    18. }
    19. ]
    20. }
    21. }
    22. }

    再次查看结果:

    这次查询出来一条数据,score变为2.9。这一条数据在上一次的查询结果中的score为1.9。然后接着往下看使用Filter。

    2.2 filter

    还是相同的需求,首先查询description中有"java程序员"。

    1. GET /book/_search
    2. {
    3. "query": {
    4. "bool": {
    5. "must": [
    6. {
    7. "match": {
    8. "description": "java程序员"
    9. }
    10. }
    11. ]
    12. }
    13. }
    14. }

    查询结果如下:

    通过查询结果可以看到,查询的两条数据的score是1.9、0.5。

    然后使用filter查询description中有"java程序员",并且价格大于80小于90的数据

    1. GET /book/_search
    2. {
    3. "query": {
    4. "bool": {
    5. "must": [
    6. {
    7. "match": {
    8. "description": "java程序员"
    9. }
    10. }
    11. ],
    12. "filter": {
    13. "range": {
    14. "price": {
    15. "gte": 80,
    16. "lte": 90
    17. }
    18. }
    19. }
    20. }
    21. }
    22. }

    查询结果如下:

    可以看到,查询出来的数据与使用query查询结果一样,但是score依旧为1.9。

    说明在使用query查询的过程中,影响到了相关度(score)的排序,在使用filter进行查询,并不会影响相关度(score)的计算。

    2.3  filter与query对比

    filter,仅仅只是按照搜索条件过滤出需要的数据而已,不计算任何相关度分数,对相关度没有任何影响。

    query,会去计算每个document相对于搜索条件的相关度,并按照相关度进行排序。

    应用场景:

    一般来说,如果你是在进行搜索,需要将最匹配搜索条件的数据先返回,那么用query。如果你只是要根据一些条件筛选出一部分数据,不关注其排序,那么用filter。

    2.4 filter与query性能

    filter,不需要计算相关度分数,不需要按照相关度分数进行排序,同时还有内置的自动cache最常使用filter的数据。比如在范围查询,keyword字段查询中推荐使用filter来进行查询。

    query,相反,要计算相关度分数,按照分数进行排序,而且无法cache结果。

    在同等查询结果下,filter的性能一般是要优于query的。

    3、explain分析语法

    在实际的应用过程中,需要查询的逻辑一般比较复杂,那当语句冗长的时候,这时候显然不太可能通过直接执行语句来调试语法正确与否,这个时候就可以通过explain来验证语句的正确性。

    验证错误语句:

    1. GET /book/_validate/query?explain
    2. {
    3. "query": {
    4. "mach": {
    5. "description": "java程序员"
    6. }
    7. }
    8. }

    返回结果如下,错误信息为没有名叫mach的query。

    1. {
    2. "valid" : false,
    3. "error" : "org.elasticsearch.common.ParsingException: no [query] registered for [mach]"
    4. }

    再来看语句正确的情况下

    1. GET /book/_validate/query?explain
    2. {
    3. "query": {
    4. "match": {
    5. "description": "java程序员"
    6. }
    7. }
    8. }

    返回,返回结果还包含对语句的解释:从description查询java关键词,从description查询程序员关键词。

    1. {
    2. "_shards" : {
    3. "total" : 1,
    4. "successful" : 1,
    5. "failed" : 0
    6. },
    7. "valid" : true,
    8. "explanations" : [
    9. {
    10. "index" : "book",
    11. "valid" : true,
    12. "explanation" : "description:java description:程序员"
    13. }
    14. ]
    15. }

    应用场景:

    一般用在那种特别复杂庞大的搜索下,比如你一下子写了上百行的搜索,这个时候可以先用validate api去验证一下,搜索是否合法。合法以后,explain就像mysql的执行计划,可以看到搜索的目标等信息。

  • 相关阅读:
    vue.draggable拖动插件的使用
    测试技能提升篇——Docker的核心概念
    常用数学分析和建模软件
    力扣第463题 岛屿的周长 C++ 深度优先搜索 + 思维判断的边界
    uniapp简单实现搜索--历史记录功能
    web网页设计期末课程大作业——海贼王大学生HTML网页制作 HTML+CSS+JS网页设计期末课程大作业 web前端开发技术 web课程设计 网页规划与设计
    Centos - VXLAN 网桥
    Sonarqube 安装 及与Jenkins sonar scanner插件集成部署
    UDS知识整理(四):ECU复位——0x11服务
    针对美国国家安全局“酸狐狸”漏洞攻击武器平台的分析与应对方案建议
  • 原文地址:https://blog.csdn.net/FaithWh/article/details/126810711