DSL搜索

目录

 

请求参数的查询(QueryString)

DSL基本语法

1.分页

2.term精确搜索与match分词搜索

 4.terms 多个词语匹配检索

5.match_phrase 短语匹配

 6.match(operator)/ids

7- multi_match/boost(权重)

8.布尔查询:可以组合多重查询

9.过滤器

10.高亮highlight

11.refix-fuzzy-wildcard

12.深度分页

13.scroll 滚动搜索

14.批量查询mget

15.批量操作 bulk


请求参数的查询(QueryString)

GET     /shop/_doc/_search?q=desc:慕课网
GET     /shop/_doc/_search?q=nickname:慕&q=age:25

DSL基本语法

语法格式为一个json object,内容都是key-value键值对,json可以嵌套。
key可以是一些es的关键字,也可以是某个field字段,后面会遇到

# 查询
POST     /shop/_doc/_search
{
    "query": {
        "match": {
            "desc": "慕课网"
        }
    }
}
# 判断某个字段是否存在
{
    "query": {
        "exists": {
            "field": "desc"
        }
    }
}

1.分页

POST     /shop/_doc/_search
{
    "query": {
        "match_all": {}
    },
    "from": 0,
    "size": 10
}

{
    "query": {
        "match_all": {}
    },
    "_source": [
        "id",
        "nickname",
        "age"
    ],
    "from": 5, 从第几条数据开始
    "size": 5  数据的大小
}

2.term精确搜索与match分词搜索

  • 注:match会对慕课网先进行分词(其实就是全文检索),在查询,而term则不会,直接把慕课网作为一个整的词汇去搜索。
POST     /shop/_doc/_search
{
    "query": {
        "term": {
            "desc": "慕课网"
        }
    }
}
对比
{
    "query": {
        "match": {
            "desc": "慕课网"
        }
    }
}

 4.terms 多个词语匹配检索

相当于是tag标签查询,比如慕课网的一些课程会打上前端/后端/大数据/就业课这样的标签,可以完全匹配做类似标签的查询

 

POST     /shop/_doc/_search
{
    "query": {
        "terms": {
            "desc": ["慕课网", "学习", "骚年"]
        }
    }
}

5.match_phrase 短语匹配

match:分词后只要有匹配就返回,match_phrase:分词结果必须在text字段分词中都包含,而且顺序必须相同,而且必须都是连续的。(搜索比较严格)

slop:允许词语间跳过的数量

POST     /shop/_doc/_search
{
    "query": {
        "match_phrase": {
            "desc": {
                "query": "大学 毕业 研究生",
                "slop": 2
            }
        }
    }
}

 6.match(operator)/ids

  • or:搜索内容分词后,只要存在一个词语匹配就展示结果
  • and:搜索内容分词后,都要满足词语匹配
    POST     /shop/_doc/_search
    {
        "query": {
            "match": {
                "desc": "慕课网"
            }
        }
    }
    # 等同于
    {
        "query": {
            "match": {
                "desc": {
                    "query": "xbox游戏机",
                    "operator": "or"
                }
            }
        }
    }
    # 相当于 select * from shop where desc='xbox' or|and desc='游戏机'

    minimum_should_match: 最低匹配精度,至少有[分词后的词语个数]x百分百,得出一个数据值取整。举个例子:当前属性设置为70,若一个用户查询检索内容分词后有10个词语,那么匹配度按照 10x70%=7,则desc中至少需要有7个词语匹配,就展示;若分词后有8个,则 8x70%=5.6,则desc中至少需要有5个词语匹配,就展示。

    POST     /shop/_doc/_search
    {
        "query": {
            "match": {
                "desc": {
                    "query": "女友生日送我好玩的xbox游戏机",
                    "minimum_should_match": "60%"
                }
            }
        }
    }

    根据文档主键ids搜索

  • POST     /shop/_doc/_search
    
    {
        "query": {
            "ids": {
                "type": "_doc",
                "values": ["1001", "1010", "1008"]
            }
        }
    }

    7- multi_match/boost(权重)

  满足使用match在多个字段中进行查询的需求

POST     /shop/_doc/_search
{
    "query": {
        "multi_match": {
                "query": "皮特帕克慕课网",
                "fields": ["desc", "nickname"]

        }
    }
}

boost:权重,为某个字段设置权重,权重越高,文档相关性得分就越高。通畅来说搜索商品名称要比商品简介的权重更高。

POST     /shop/_doc/_search
{
    "query": {
        "multi_match": {
                "query": "皮特帕克慕课网",
                "fields": ["desc", "nickname^10"]

        }
    }
}

nickname^10 代表搜索提升10倍相关性,也就是说用户搜索的时候其实以这个nickname为主,desc为辅,nickname的匹配相关度当然要提高权重比例了。

8.布尔查询:可以组合多重查询

  • must:查询必须匹配搜索条件,譬如 and
  • should:查询匹配满足1个以上条件,譬如 or
  • must_not:不匹配搜索条件,一个都不要满足
    POST     /shop/_doc/_search
    
    {
        "query": {
            "bool": {
                "must": [
                    {
                        "multi_match": {
                            "query": "慕课网",
                            "fields": ["desc", "nickname"]
                        }
                    },
                    {
                        "term": {
                            "sex": 1
                        }
                    },
                    {
                        "term": {
                            "birthday": "1996-01-14"
                        }
                    }
                ]
            }
        }
    }
    
    {
        "query": {
            "bool": {
                "should(must_not)": [
                    {
                        "multi_match": {
                            "query": "学习",
                            "fields": ["desc", "nickname"]
                        }
                    },
                    {
                        "match": {
                            "desc": "游戏"
                        }   
                    },
                    {
                        "term": {
                            "sex": 0
                        }
                    }
                ]
            }
        }
    }

为指定词语加权 

POST     /shop/_doc/_search
{
    "query": {
        "bool": {
            "should": [
                {
                    "match": {
                        "desc": {
                            "query": "律师",
                            "boost": 18
                        }
                    }
                },
                {
                    "match": {
                        "desc": {
                            "query": "进修",
                            "boost": 2
                        }
                    }
                }
            ]
        }
    }
}

9.过滤器

对搜索出来的结果进行数据过滤。不会到es库里去搜,不会去计算文档的相关度分数,所以过滤的性能会比较高,过滤器可以和全文搜索结合在一起使用。
post_filter元素是一个顶层元素,只会对搜索结果进行过滤。不会计算数据的匹配度相关性分数,不会根据分数去排序,query则相反,会计算分数,也会按照分数去排序。
使用场景:

  • query:根据用户搜索条件检索匹配记录
  • post_filter:用于查询后,对结果数据的筛选
    实操:查询账户金额大于80元,小于160元的用户。并且生日在1998-07-14的用户
  • gte:大于等于
  • lte:小于等于
  • gt:大于

lt:小于

POST     /shop/_doc/_search

{
    "query": {
        "match": {
            "desc": "慕课网游戏"
        }   
    },
    "post_filter": {
        "range": {
            "money": {
                "gt": 60,
                "lt": 1000
            }
        }
    }   
}

10.高亮highlight

POST     /shop/_doc/_search
{
    "query": {
        "match": {
            "desc": "慕课网"
        }
    },
    "highlight": {
        "pre_tags": ["<tag>"],
        "post_tags": ["</tag>"],
        "fields": {
            "desc": {}
        }
    }
}

11.refix-fuzzy-wildcard

prefix前缀

POST     /shop/_doc/_search
{
    "query": {
        "prefix": {
            "desc": "imo"
        }
    }
}

fuzzy

模糊搜索,并不是指的sql的模糊搜索,而是用户在进行搜索的时候的打字错误现象,搜索引擎会自动纠正,然后尝试匹配索引库中的数据。

POST     /shop/_doc/_search
{
  "query": {
    "fuzzy": {
      "desc": "imoov.coom"
    }
  }
}
# 或多字段搜索
{
  "query": {
    "multi_match": {
      "fields": [ "desc", "nickname"],
      "query": "imcoc supor",
      "fuzziness": "AUTO"
    }
  }
}

{
  "query": {
    "multi_match": {
      "fields": [ "desc", "nickname"],
      "query": "演说",
      "fuzziness": "1"
    }
  }
}

wildcard:

占位符查询。
?:1个字符   *:1个或多个字符

POST     /shop/_doc/_search
{
  "query": {
    "wildcard": {
      "desc": "*oo?"
    }
  }
}
{
    "query": {
        "wildcard": {
            "desc": "演*"
        }
    }
}

12.深度分页

  分页查询

POST     /shop/_doc/_search
{
    "query": {
        "match_all": {}
    },
    "from": 0,
    "size": 10
}

深度分页:深度分页其实就是搜索的深浅度,比如第1页,第2页,第10页,第20页,是比较浅的;第10000页,第20000页就是很深了。

{
    "query": {
        "match_all": {}
    },
    "from": 9990,
    "size": 10
}

{
    "query": {
        "match_all": {}
    },
    "from": 9999,
    "size": 10
}

我们在获取第9999条到10009条数据的时候,其实每个分片都会拿到10009条数据,然后集合在一起,总共是10009*3=30027条数据,针对30027数据再次做排序处理,最终会获取最后10条数据。

如此一来,搜索得太深,就会造成性能问题,会耗费内存和占用cpu。而且es为了性能,他不支持超过一万条数据以上的分页查询。那么如何解决深度分页带来的性能呢?其实我们应该避免深度分页操作(限制分页页数),比如最多只能提供100页的展示,从第101页开始就没了,毕竟用户也不会搜的那么深,我们平时搜索淘宝或者百度,一般也就看个10来页就顶多了。

提升搜索量:通过设置index.max_result_window来突破10000数据

GET     /shop/_settings

PUT     /shop/_settings
{ 
    "index.max_result_window": "20000"
}

13.scroll 滚动搜索

一次性查询1万+数据,往往会造成性能影响,因为数据量太多了。这个时候可以使用滚动搜索,也就是 scroll。
滚动搜索可以先查询出一些数据,然后再紧接着依次往下查询。在第一次查询的时候会有一个滚动id,相当于一个锚标记,随后再次滚动搜索会需要上一次搜索的锚标记,根据这个进行下一次的搜索请求。每次搜索都是基于一个历史的数据快照,查询数据的期间,如果有数据变更,那么和搜索是没有关系的,搜索的内容还是快照中的数据。

https://www.elastic.co/guide/cn/elasticsearch/guide/current/scroll.html
scroll=1m,相当于是一个session会话时间,搜索保持的上下文时间为1分钟。

POST    /shop/_search?scroll=1m
{
    "query": { 
        "match_all": {
        }
    },  
    "sort" : ["_doc"], 
    "size":  5
}

POST    /_search/scroll
{
    "scroll": "1m", 
    "scroll_id" : "your last scroll_id"
}

14.批量查询mget

http://192.168.35.132:9200/shop/_doc/_mget
{
      "ids":["1001","1002"]

}

结果:"found": true表示有数据,false表示没有数据

{
    "docs": [
        {
            "_index": "shop",
            "_type": "_doc",
            "_id": "1001",
            "_version": 1,
            "_seq_no": 0,
            "_primary_term": 1,
            "found": true,
            "_source": {
                "id": 1001,
                "age": 18,
                "username": "imoocAmazing",
                "nickname": "慕课网",
                "money": 88.8,
                "desc": "我在慕课网学习java和前端,学习到了很多知识",
                "sex": 0,
                "birthday": "1992-12-24",
                "face": "https://www.imooc.com/static/img/index/logo.png"
            }
        },
        {
            "_index": "shop",
            "_type": "_doc",
            "_id": "1002",
            "_version": 1,
            "_seq_no": 0,
            "_primary_term": 1,
            "found": true,
            "_source": {
                "id": 1002,
                "age": 19,
                "username": "justbuy",
                "nickname": "周杰棍",
                "money": 77.8,
                "desc": "今天上下班都很堵,车流量很大",
                "sex": 1,
                "birthday": "1993-01-24",
                "face": "https://www.imooc.com/static/img/index/logo.png"
            }
        }
    ]
}

15.批量操作 bulk

bulk操作和以往的普通请求格式有区别。不要格式化json,不然就不在同一行了,这个需要注意。

 action: { metadata }}\n
{ request body        }\n
{ action: { metadata }}\n
{ request body        }\n

{ action: { metadata }}代表批量操作的类型,可以是新增、删除或修改
\n是每行结尾必须填写的一个规范,每一行包括最后一行都要写,用于es的解析
{ request body }是请求body,增加和修改操作需要,删除操作则不需要

批量操作的类型

 

-create新增文档数据,在metadata中指定index以及type

POST    /_bulk
{"create": {"_index": "shop2", "_type": "_doc", "_id": "2001"}}
{"id": "2001", "nickname": "name2001"}
{"create": {"_index": "shop2", "_type": "_doc", "_id": "2002"}}
{"id": "2002", "nickname": "name2002"}
{"create": {"_index": "shop2", "_type": "_doc", "_id": "2003"}}
{"id": "2003", "nickname": "name2003"}
  • create创建已有id文档,在url中指定index和type
POST    /shop/_doc/_bulk
{"create": {"_id": "2003"}}
{"id": "2003", "nickname": "name2003"}
{"create": {"_id": "2004"}}
{"id": "2004", "nickname": "name2004"}
{"create": {"_id": "2005"}}
{"id": "2005", "nickname": "name2005"}
  • index创建,已有文档id会被覆盖,不存在的id则新增
POST    /shop/_doc/_bulk
{"index": {"_id": "2004"}}
{"id": "2004", "nickname": "index2004"}
{"index": {"_id": "2007"}}
{"id": "2007", "nickname": "name2007"}
{"index": {"_id": "2008"}}
{"id": "2008", "nickname": "name2008"}
  • update跟新部分文档数据
POST    /shop/_doc/_bulk
{"update": {"_id": "2004"}}
{"doc":{ "id": "3004"}}
{"update": {"_id": "2007"}}
{"doc":{ "nickname": "nameupdate"}}
  • delete批量删除
POST    /shop/_doc/_bulk
{"delete": {"_id": "2004"}}
{"delete": {"_id": "2007"}}
POST    /shop/_doc/_bulk
{"create": {"_id": "8001"}}
{"id": "8001", "nickname": "name8001"}
{"update": {"_id": "2001"}}
{"doc":{ "id": "20010"}}
{"delete": {"_id": "2003"}}
{"delete": {"_id": "2005"}}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章