主要内容:match all 等查询类型,多条件组合查询和利用filter进行查询的优化,还简单介绍了排序以及字符串排序
1、查询类型归纳
1、match all
查询所有:
GET /_search
{
"query": {
"match_all": {}
}
}
2、match
匹配相关field的文本:
GET /_search
{
"query": { "match": { "title": "my elasticsearch article" }}
}
3、multi match
将一段搜索的文本使用到多个field上,例如 搜索test_field和test_field1上的匹配test的document
GET ecommerce/_search
{
"query": {
"multi_match": {
"query": "fangzhu",
"fields": ["tags","name"]
}
}
}
4、range query
可以放在query和filter里面,例子:查询年龄大于35岁的员工
GET /company/_search
{
"query": {
"range": {
"age": {
"gte": 30
}
}
}
}
5、term query
会将搜索词作为整个词到倒排索引中查询
GET /test_index/_search
{
"query": {
"term": {
"title": "xiaomi"
}
}
}
6、terms query
指定多个term的搜索词:
title匹配xiaomi或者huawei的document
GET /test_index/_search
{
"query": {
"terms": {
"title": [
"xiaomi",
"huawei"
]
}
}
}
2、多条件组合查询
多条件的话,在query下加bool,然后在bool下可以加以下四种条件:
must,must_not,should,filter
GET /company/_search
{
"query": {
"bool": {
"must": [{"match": {"name": "marry"}}],
"must_not": [{"match": {"address.city": "nanjing"}}],
"should": [{"match": {"address.province": "jiangsu"}}],
"filter": {"range": {"join_date": {"lte": "2016-01-01"}}}
}
}
}
每个子查询都会计算一个document针对它的相关度分数,然后bool综合所有分数,合并为一个分数,当然filter是不会计算分数的
GET /company/_search
{
"query": {
"constant_score": {
"filter": {
"range": {
"age": {
"gte": 30
}
}
}
}
}
}
当我们不关心检索词频率TF(Term Frequency)对搜索结果排序的影响时,可以使用constant_score将查询语句query或者过滤语句filter包装起来。
3、利用filter进行查询的优化
{
"query" : {
"bool" : {
"must" : [
{
"term" : { "name" : "joe" }
},
{
"term" : { "year" : 1981 }
}
]
}
}
}
如果用上面命令的格式构建查询,查询对象会将所有的条件绑定到一起存储到缓存中;因此如果我们查询人名相同但是出生年份不同的运动员,ElasticSearch无法重用上面查询命令中的任何信息。因此,我们来试着优化一下查询。由于一千个人可能会有一千个人名,所以人名不太适合缓存起来;但是年份比较适合:
{
"query" : {
"filtered" : {
"query" : {
"term" : { "name" : "joe" }
},
"filter" : {
"term" : { "year" : 1981 }
}
}
}
}
我们使用了一个filtered类型的查询对象,查询对象将query元素和filter元素都包含进去了。第一次运行该查询命令后,ElasticSearch就会把filter缓存起来,如果再有查询用到了一样的filter,就会直接用到缓存。就这样,ElasticSearch不必多次加载同样的信息。
4、快速定位不合法的搜索(validate)
一般用在那种特别复杂庞大的搜索下,比如你一下子写了上百行的搜索,这个时候可以先用validate api去验证一下,搜索是否合法
GET /test_index/_validate/query?explain
{
"query": {
"math": {
"test_field": "test"
}
}
}
5、复习自定义排序
GET /company/_search
{
"query": {
"constant_score": {
"filter": {
"range": {
"age": {
"gte": 30
}
}
}
}
},
"sort": [
{
"join_date": {
"order": "asc"
}
}
]
}
6、字符串排序问题
如果对一个string field进行排序,结果往往不准确,因为分词后是多个单词,再排序就不是我们想要的结果了
通常解决方案是,将一个string field建立两次索引,一个分词,用来进行搜索;一个不分词,用来进行排序
创建示例索引
PUT /website
{
"mappings": {
"properties": {
"title": {
"type": "text",
"fields": {
"raw": {
"type": "keyword"
}
},
"fielddata": true
},
"content": {
"type": "text"
},
"post_date": {
"type": "date"
},
"author_id": {
"type": "long"
}
}
}
}
插入数据
PUT website/_doc/1
{"title":"first article","content":"this is my first article","post_date":"2017-02-01","author_id":110}
PUT website/_doc/2
{"title":"second article","content":"this is my second article","post_date":"2017-01-01","author_id":110}
PUT website/_doc/3
{"title":"third article","content":"this is my third article","post_date":"2017-03-01","author_id":110}
开始查询,使用title.raw进行分词,title进行查询
GET /website/_search
{
"query": {
"match_all": {}
},
"sort": [
{
"title.raw": {
"order": "desc"
}
}
]
}
参考的文章:
Elasticsearch查询性能优化 - 简书 https://www.jianshu.com/p/6b5ddb594b1b
相关拓展:
为什么Elasticsearch查询变得这么慢了?大数据铭毅天下(公众号同名)-CSDN博客 https://blog.csdn.net/laoyang360/article/details/83048087
网友评论