美文网首页Java 程序员Java
ElasticsearchDSL查询语法,es构建复杂查询

ElasticsearchDSL查询语法,es构建复杂查询

作者: 马小莫QAQ | 来源:发表于2021-02-06 22:33 被阅读0次

    1. 数据准备

    • 1.1 先新建索引index,索引名称:shop
    • 1.2 添加以下字段
    {
        "properties": {
            "id": {
                "type": "long"
            },
            "age": {
                "type": "integer"
            },
            "username": {
                "type": "keyword"
            },
            "nickname": {
                "type": "text",
                "analyzer": "ik_max_word"
            },
            "money": {
                "type": "float"
            },
            "desc": {
                "type": "text",
                "analyzer": "ik_max_word"
            },
            "sex": {
                "type": "byte"
            },
            "birthday": {
                "type": "date"
            },
            "face": {
                "type": "text",
                "index": false
            }
        }
    }
    

    HTTP POST请求创建以上字段

    POST /shop/_mapping HTTP/1.1
    Host: 192.168.10.235:9200
    Content-Type: application/json
    Content-Length: 654
    
    {
        "properties": {
            "id": {
                "type": "long"
            },
            "age": {
                "type": "integer"
            },
            "username": {
                "type": "keyword"
            },
            "nickname": {
                "type": "text",
                "analyzer": "ik_max_word"
            },
            "money": {
                "type": "float"
            },
            "desc": {
                "type": "text",
                "analyzer": "ik_max_word"
            },
            "sex": {
                "type": "byte"
            },
            "birthday": {
                "type": "date"
            },
            "face": {
                "type": "text",
                "index": false
            }
        }
    }
    
    • 1.3 添加测试数据

    HTTP POST请求

    POST /shop/_doc/1001 HTTP/1.1
    Host: 192.168.10.235:9200
    Content-Type: application/json
    Content-Length: 335
    
    {
        "id": 1001,
        "age": 18,
        "username": "zhangsan",
        "nickname": "张三",
        "money": 199.8,
        "desc": "我是张三,我现在在学习Elasticsearch",
        "sex": 0,
        "birthday": "2003-09-01",
        "face": "http://www.imooc.com/static/img/index/logo.png"
    }
    

    完整的post请求链接为:http://192.168.10.235:9200/shop/_doc/1001

    链接末尾的1001与json中的id:1001最好对应上。

    按此格式,添加多条用于测试的数据即可。

    2. 简单数据查询

    • 2.1 GET 请求查询数据(无条件,查询全部)
    http://192.168.10.235:9200/shop/_search
    
    • 2.2 GET 请求查询数据(添加查询条件)
    一个查询条件
    http://192.168.10.235:9200/shop/_search?q=nickname:张三
    多个查询条件
    http://192.168.10.235:9200/shop/_search?q=nickname:张三&q=desc:学习
    
    • 2.3 POST 请求查询数据
    POST /shop/_search HTTP/1.1
    Host: 192.168.10.235:9200
    Content-Type: application/json
    Content-Length: 79
    
    {
        "query": {
            "match": {
                "nickname": "张三"
            }
        }
    }
    

    post请求链接固定:http://192.168.10.235:9200/shop/_search

    搜索条件写在json中,match为es中的关键字,如果你写错,执行请求就会报错。

    3. DSL搜索-全部查询、分页查询

    • 3.1 GET 请求
    http://192.168.10.235:9200/shop/_search
    
    • 3.2 POST 请求,使用es关键字 match_all
    POST /shop/_search HTTP/1.1
    Host: 192.168.10.235:9200
    Content-Type: application/json
    Content-Length: 48
    
    {
        "query": {
            "match_all": {}
        }
    }
    

    查询全部建议使用post方式,因为后期如果需要添加分页、过滤等功能,get请求链接会越来越复杂。

    • 3.3 只返回指定字段,使用 _source
    POST /shop/_search HTTP/1.1
    Host: 192.168.10.235:9200
    Content-Type: application/json
    Content-Length: 120
    
    {
        "query": {
            "match_all": {}
        },
        "_source": [
            "id",
            "nickname",
            "age"
        ]
    }
    

    这样查询结果就只会返回 id、nickname、age 三个指定的字段。

    • 3.4 分页查询,使用 from、size
    POST /shop/_search HTTP/1.1
    Host: 192.168.10.235:9200
    Content-Type: application/json
    Content-Length: 151
    
    {
        "query": {
            "match_all": {}
        },
        "_source": [
            "id",
            "nickname",
            "age"
        ],
        "from": 0,
        "size": 10
    }
    

    from:从第几条数据开始

    size:一页返回多少条数据

    4. DSL搜索-不进行分词搜索 term

    match在查询时,是进行了分词的操作

    而term是代表完全匹配,即不进行分词器分析,文档中必须包含整个搜索的词汇

    POST /shop/_search HTTP/1.1
    Host: 192.168.10.235:9200
    Content-Type: application/json
    Content-Length: 77
    
    {
        "query": {
            "term": {
                "desc": "学习"
            }
        }
    }
    

    搜索在desc中包含 “学习” 的数据

    如果需要匹配多个词,则可以使用 terms

    POST /shop/_search HTTP/1.1
    Host: 192.168.10.235:9200
    Content-Type: application/json
    Content-Length: 77
    
    {
        "query": {
            "terms": {
                "desc": ["在","学习"]
            }
        }
    }
    

    5. DSL搜索-临近搜索词 match_phrase

    现在有两条数据,desc 分别为:

    第一条:“你大学已经毕业了吗?”

    第二条:“我在大学毕业后,考研究生去了”

    现在使用 match_phrase 来进行查询

    POST /shop/_search HTTP/1.1
    Host: 192.168.10.235:9200
    Content-Type: application/json
    Content-Length: 129
    
    {
        "query": {
            "match_phrase": {
                "desc": {
                    "query": "大学 毕业"
                }
            }
        }
    }
    

    此时只能查询出来第二条数据,第一条数据是匹配不到的,

    match_phrase 要求 大学 的后面,必须是 毕业 两个字,只有满足“大学毕业”的才算符合条件;

    那怎样才能同时查询出第一条和第二条数据呢

    可以使用关键字 slop,即中间跳过一定的字符

    比如第一条 大学毕业 中间隔了两个字符,使用 "slop": 2

    POST /shop/_search HTTP/1.1
    Host: 192.168.10.235:9200
    Content-Type: application/json
    Content-Length: 156
    
    {
        "query": {
            "match_phrase": {
                "desc": {
                    "query": "大学 毕业",
                    "slop": 2
                }
            }
        }
    }
    

    只要 slop 大于等于2,两条数据都能查询出来。

    关于 match_phrase 具体解释和用法,也可以看官方文档 短语匹配

    5. DSL搜索-操作符 operator

    先看请求

    POST /shop/_search HTTP/1.1
    Host: 192.168.10.235:9200
    Content-Type: application/json
    Content-Length: 154
    
    {
        "query": {
            "match": {
                "desc": {
                    "query": "在学习",
                    "operator": "or"
                }
            }
        }
    }
    

    我们知道 match 会进行分词操作,在查询时,会将 “在学习” 分成 “在”“学习” 两个词进行检索匹配

    使用or,则会查询出在desc中包含 “在” 或包含 “学习” 的数据

    如果使用 and ("operator": "and"),则只会查询出在desc中包含 “在学习” 的数据

    如果 query 条件是一句话,比如:“让开发者成为一个令人尊敬的职业”,此时则会分词成很多个词,匹配到的数据也有很多,使得查询精度不够高,

    这时就可以使用 minimum_should_match 来提高匹配精度。

    我们先看看es会将 “让开发者成为一个令人尊敬的职业” 这一句话分成多少个词?

    POST /_analyze HTTP/1.1
    Host: 192.168.10.235:9200
    Content-Type: application/json
    Content-Length: 64
    
    {
        "analyzer": "ik_max_word",
        "text": "让开发者成为一个令人尊敬的职业"
    }
    

    查询结果显示是分成了 13 个词,所以如果是直接去匹配的话,则会查询出来很多数据

    minimum_should_match 代表最小被匹配到的

    POST /shop/_search HTTP/1.1
    Host: 192.168.10.235:9200
    Content-Type: application/json
    Content-Length: 167
    
    {
        "query": {
            "match": {
                "desc": {
                    "query": "让开发者成为一个令人尊敬的职业",
                    "minimum_should_match": "60%"
                }
            }
        }
    }
    

    这里 60% 则表示,搜索结果要满足 13 个词的60%(含)以上,即 13*0.6=7.8,向下取整为7

    需要包含7个(包括7)以上的词,而不是只包含其中的一个词。

    这里不仅可以写百分比,也可以直接写数字,比如:"minimum_should_match": "3"

    则表示是包含 3 个(包括3)词以上的

    6. DSL搜索-根据id查询数据 ids

    这个比较简单,使用关键字 ids 即可,可以查询多个

    POST /shop/_search HTTP/1.1
    Host: 192.168.10.235:9200
    Content-Type: application/json
    Content-Length: 164
    
    {
        "query": {
            "ids": {
                "type": "_doc",
                "values": [
                    "1001",
                    "1006"
                ]
            }
        }
    }
    

    values数组中填写要查询的id就行。

    7. DSL搜索-多重查询 multi_match 和提高指定字段权重

    多重查询的意思就是使用多个字段去做查询

    现在有这两条数据:

    我要查询 nicknamedesc 都包含 沙僧 的数据

    使用关键字 multi_match

    POST /shop/_search HTTP/1.1
    Host: 192.168.10.235:9200
    Content-Type: application/json
    Content-Length: 175
    
    {
        "query": {
            "multi_match": {
                "query": "沙僧",
                "fields": [
                    "nickname",
                    "desc"
                ]
            }
        }
    }
    

    提高指定字段的权重,使用 ^

    比如我要提高nickname在查询中的权重,则只需要在 nickname 后加上 ^数字

    POST /shop/_search HTTP/1.1
    Host: 192.168.10.235:9200
    Content-Type: application/json
    Content-Length: 175
    
    {
        "query": {
            "multi_match": {
                "query": "沙僧",
                "fields": [
                    "nickname^10",
                    "desc"
                ]
            }
        }
    }
    

    这样查询出来的结果排序和默认的则不一样了。

    而且返回的数据中 max_score_score 的值也有变化

    7. DSL搜索-组合查询 bool

    将多个条件组合在一起

    • 7.1 must:是指要同时满足下面的两个条件
    POST /shop/_search HTTP/1.1
    Host: 192.168.10.235:9200
    Content-Type: application/json
    Content-Length: 481
    
    {
        "query": {
            "bool": {
                "must": [
                    {
                        "multi_match": {
                            "query": "沙僧",
                            "fields": [
                                "nickname",
                                "desc"
                            ]
                        }
                    },
                    {
                        "term": {
                            "sex": 0
                        }
                    }
                ]
            }
        }
    }
    
    • 7.2 should:下面的两个条件,满足一个就行
    {
        "query": {
            "bool": {
                "should": [
                    {
                        "multi_match": {
                            "query": "沙僧",
                            "fields": [
                                "nickname",
                                "desc"
                            ]
                        }
                    },
                    {
                        "term": {
                            "sex": 0
                        }
                    }
                ]
            }
        }
    }
    
    • 7.3 must_not:下面的两个条件,都不能满足,和 must 相反
    {
        "query": {
            "bool": {
                "must_not": [
                    {
                        "multi_match": {
                            "query": "沙僧",
                            "fields": [
                                "nickname",
                                "desc"
                            ]
                        }
                    },
                    {
                        "term": {
                            "sex": 0
                        }
                    }
                ]
            }
        }
    }
    
    • 7.4 mustmust_notshould 可以同时使用
    POST /shop/_search HTTP/1.1
    Host: 192.168.10.235:9200
    Content-Type: application/json
    Content-Length: 771
    
    {
        "query": {
            "bool": {
                "must": [
                    {
                        "match": {
                            "desc": "大学"
                        }
                    }
                ],
                "must_not": [
                    {
                        "term": {
                            "sex": "1"
                        }
                    }
                ],
                "should": [
                    {
                        "range": {
                            "age": {
                                "gt": "18",
                                "lt": "22"
                            }
                        }
                    },
                    {
                        "match": {
                            "desc": "毕业"
                        }
                    }
                ]
            }
        }
    }
    

    8. DSL搜索-过滤器 post_filter

    将金额money小于100并且大于1000的数据过滤掉

    POST /shop/_search HTTP/1.1
    Host: 192.168.10.235:9200
    Content-Type: application/json
    Content-Length: 226
    
    {
        "query": {
            "match": {
                "desc": "大学"
            }
        },
        "post_filter": {
            "range": {
                "money": {
                    "gt": 100,
                    "lt": 1000
                }
            }
        }
    }
    

    post_filterquery 是同级的

    9. DSL搜索-排序 sort

    es默认是按 _score 排序

    正序asc

    倒序desc

    POST /shop/_search HTTP/1.1
    Host: 192.168.10.235:9200
    Content-Type: application/json
    Content-Length: 144
    
    {
        "query": {
            "match": {
                "desc": "大学"
            }
        },
        "sort": [
            {
                "age": "asc"
            }
        ]
    }
    

    多个排序条件,组合排序

    POST /shop/_search HTTP/1.1
    Host: 192.168.10.235:9200
    Content-Type: application/json
    Content-Length: 193
    
    {
        "query": {
            "match": {
                "desc": "大学"
            }
        },
        "sort": [
            {
                "age": "asc"
            },
            {
                "money": "desc"
            }
        ]
    }
    

    text类型无法排序,keyword类型可以

    10. DSL搜索-关键字高亮显示 highlight

    POST /shop/_search HTTP/1.1
    Host: 192.168.10.235:9200
    Content-Type: application/json
    Content-Length: 157
    
    {
        "query": {
            "match": {
                "desc": "沙僧"
            }
        },
        "highlight": {
            "fields": {
                "desc": {}
            }
        }
    }
    

    返回的数据中会对搜索关键字增加一个 em 标签

    "highlight": {
        "desc": [
            "唐三藏是<em>沙僧</em>的师傅"
        ]
    }
    

    我们也可以自定义这个标签,使用 pre_tagspost_tags

    POST /shop/_search HTTP/1.1
    Host: 192.168.10.235:9200
    Content-Type: application/json
    Content-Length: 267
    
    {
        "query": {
            "match": {
                "desc": "沙僧"
            }
        },
        "highlight": {
            "pre_tags": [
                "<span>"
            ],
            "post_tags": [
                "</span>"
            ],
            "fields": {
                "desc": {}
            }
        }
    }
    

    这样返回的数据中,em标签 则改成了 span

    "highlight": {
        "desc": [
            "唐三藏是<span>沙僧</span>的师傅"
        ]
    }
    

    作者:_灯火阑珊处
    链接:https://juejin.cn/post/6925707999247876110
    来源:掘金

    相关文章

      网友评论

        本文标题:ElasticsearchDSL查询语法,es构建复杂查询

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