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 和提高指定字段权重
多重查询的意思就是使用多个字段去做查询
现在有这两条数据:

我要查询 nickname 和 desc 都包含 沙僧 的数据
使用关键字 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 must、must_not、should 可以同时使用
 
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_filter 和 query 是同级的
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_tags 和 post_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>的师傅"
    ]
}










