Elasticsearch——dsl搜索

本文涉及的产品
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
简介: 个人学习笔记——ES

准备工作

新建一个shop索引,并添加mappings

{
    "properties": {
        "id": {
            "type": "long"
        },
        "age": {
            "type": "integer"
        },
        "username": {
            "type": "keyword"
        },
        "nickname": {
            "type": "text"
        },
        "money": {
            "type": "float"
        },
        "desc": {
            "type": "text",
            "analyzer": "ik_max_word"
        },
        "sex": {
            "type": "byte"
        },
        "birthday": {
            "type": "date"
        },
        "face": {
            "type": "text",
            "index": false
        }
    }
}

数据准备

QueryString数据查询

Get请求:http://{IP}:{port}/{索引名称}/_search?q={字段field}:{搜索内容}
在这里插入图片描述
多条件查询:
Get请求:http://{IP}:{port}/{索引名称}/_search?q={字段field}:{搜索内容}&q={字段field}:{搜索内容}

dsl数据查询

match搜索

Post请求:http://{IP}:{port}/{索引名称}/_doc/_search
就是与q={字段field}:{搜索内容}相同功能

查询所有

指定字段查询

增加_source搜索条件,往数组中添加自己需要的字段

分页搜索

增加from、size查询条件

exists搜索

判断某个字段是否存在,存在的话就把数据返回回来

可视化界面查询

term和match

term

term是把字段当做keyword,不会进行分词
如下:
二字就是一个分词,会去匹配desc中包含“二字”的内容

terms

传入一个数组,去匹配desc包含“快快乐乐” “高高兴兴”的内容

match

match会把字段的内容进行分词
如下,会把二字分词为二,词,二词

match_phrase

"query":"恍恍惚惚 嘻嘻哈哈"的意思表达是,我所匹配的内容中,必须是连贯的,比如恍恍惚惚后面必须紧跟的是嘻嘻哈哈,否则是不会匹配到的

还有一种方式,比如你就是想后面不是连贯的匹配,可以使用slop,slop的意思是允许你中间可以有多少分词间隔

match进一步了解

operator

可以对match查询增加operator,默认是or条件,也就是查询的信息里只要匹配到分词:小,二,小二就可以。

但是如果把operator改为and,那么在匹配的内容中必须同时出现分词内容,也就是小、二这两个词必须出现,顺序没有关系。

minimum_should_match

对于operator的and和or是两种极端情况,如果需要对匹配内容达到一定比例进行查询就可以使用minimum_should_match,如果minimum_should_match使用百分比那么就对对于匹配的内容达到这个百分比就可以查询出来。
当然也可以使用数值:1,2,3这些,这样的话就是当有1个值匹配到就查询出来,2个值匹配到就查询出来,以此类推。
在这里插入图片描述

ids查询

其实就是多id查询数据,有命中多少条就返回多少数据

multi_match

多字段的匹配查询,fields中就去放入想要匹配的字段


当需要对某个字段进行权重设置,也就是希望查询出来的某个字段匹配的数据信息往前排,就可以通过权重来实现
这里我给desc设置了权重,这样他的score就变大了,score越大,他在返回数据的排名中就越靠前

布尔查询

通过可视化查询可以看到boo的查询语句,bool查询包含must、must_not、should,是一种组合的查询方式,每一种查询都可以包含很多条件去查询,因为这3中查询他每一个都是一个数组。
must: 条件必须都匹配,相当于sql中的and查询。
must_not: 条件不匹配,把不满足条件的内容查询出来。
should: 相当于sql中的or查询,这个查询中的条件只要满足或者即可。

must查询

查询desc、nickname字段包含恍恍惚惚分词,并且sex为1的数据

{
    "query": {
        "bool": {
            "must": [
                {
                    "multi_match": {
                        "query": "恍恍惚惚",
                        "fields": [
                            "desc",
                            "nickname"
                        ]
                    }
                },
                {
                    "term": {
                        "sex": 1
                    }
                }
            ]
        }
    },
    "_source": [
        "id",
        "sex",
        "nickname",
        "desc"
    ]
}

should

当把must改为should之后,匹配到的数量就变为了7条,因为只要满足其中一个条件即可。

must_not

当改为must_not之后,查询结果就只有5条了,把不满足条件的数据全部查询出来,就跟should查询的数据量相加就是数据总量。

must、must_not、should组合查询

查询desc字段包含“恍恍惚惚”分词的,或者sex匹配“1”的数据,并且birthday字段内容不为“1989-06-12”的内容。

{
    "query": {
        "bool": {
            "must": [
                {
                    "match": {
                        "desc": "恍恍惚惚"
                    }
                }
            ],
            "should": [
                {
                    "match": {
                        "sex": 0
                    }
                }
            ],
            "must_not": [
                {
                    "term": {
                        "birthday": "1989-06-12"
                    }
                }
            ]
        }
    },
    "_source": [
        "id",
        "sex",
        "nickname",
        "desc",
        "birthday"
    ]
}

boost权重

可以通过设置boost权重来提高要查询的内容的分数(排名)排在前面

post_filter 过滤器

主要是针对于查询出的结果,在进行一次过滤,如下:
先匹配desc内容之后再进行money数值的过滤,下面是money的值大于50且小于100。
query是去es里检索的,post_filter去针对于query检索出来的数据进行的再次筛选。

{
    "query": {
        "match": {
            "desc": "恍恍惚惚"
        }
    },
    "post_filter": {
        "range": {
            "money": {
                "gt": 50,
                "lt": 100
            }
        }
    }
}

sort排序

顾名思义,就是排序。
如下:
先根据money字段升序,再根据age降序

{
    "query": {
        "match": {
            "desc": "恍恍惚惚"
        }
    },
    "sort": [
        {
            "money": "asc"
        },
        {
            "age": "desc"
        }
    ]
}


注意:
对于text类型的字段是不能直接进行排序的,必须给他添加一个附加类型keyword,因为text类型是可以进行多个分词的,这时候不知道是该如何进行排序的。此时只能用keyword进行进行排序。

演示keyword排序

新建一个shop2索引,新建mapping

{
    "properties": {
        "id": {
            "type": "long"
        },
        "nickname": {
            "type": "text",
            "analyzer": "ik_max_word",
            # 创建附加类型
            "fields":{
                "keyword":{
                    "type": "keyword"
                }
            }
        }
    }
}

自行添加数据之后进行nickname的排序查询

使用文本的排序应用场景也是比较少的

高亮

通过增加highlight来设置高亮,es默认是使用em标签来高亮

{
    "query": {
        "match": {
            "desc": "恍恍惚惚"
        }
    },
    "highlight": {
        "fields": {
            "desc": {}
        }
    }
}


通过自定义高亮标签来返回

"pre_tags":["<span>"],
"post_tags":["</span>"]

深度分页

当只是查询第10、20页,这还只是浅分页,当页码数越大越靠后时,就会产生深度分页。
当ES的from达到9999,size为10时,ES自己做了一层校验,来进行提示。以免我们分页太深,对性能造成影响。

Result window is too large, from + size must be less than or equal to:
[10000] but was [10009]. See the scroll api for a more efficient way
to request large data sets. This limit can be set by changing the
[index.max_result_window] index level setting.

ES之

比如当前有3个shard,那么对于ES来说是从每个shard中拿10009条数据,然后汇总为30029条数据,再从30029中排序拿到前10条数据,那么另外的30019条数据就是无效的,在这个过程中就有性能的损耗。
一般这种情况使用业务来进行规避,比如淘宝的搜索,页面就已经限制了最大100页的分页。

提示搜索量

Result window is too large, from + size must be less than or equal to:
[10000] but was [10009]. See the scroll api for a more efficient way
to request large data sets. This limit can be set by changing the
[index.max_result_window] index level setting.

在上面的深度分页中,ES也有提示,可以设置index.max_result_window提升10000的限制。


可以通过查看设置,数量限制已经生效,在没有设置之前可能看不到这个属性。

这个时候再去查询9999分页就没有问题了

scroll滚动搜索(游标搜索)

当分页到99999会进行如下提示:

Result window is too large, from + size must be less than or equal to:
[100000] but was [100009]. See the scroll api for a more efficient way
to request large data sets. This limit can be set by changing the
[index.max_result_window] index level setting.

如果一下子要查询出10W的数据量,那肯定是对性能有影响的,那么ES提示可以使用滚动搜索。
那么对于滚动搜索就是,分批次进行加载数据,比如先查询一部分数据,再依次往下查询。
在第一次查询的时候,会有一个滚动的ID(类似锚标记),在下一次请求的时候只需要把上一次的锚标记拿到,传给下一次的查询就可以往下查询。如果查询过程中有数据变更,不会影响搜索结果(查询的是快照数据)。

第一次查询:
POST:http://{IP}:{port}/{索引}/_doc/_search?scroll={时间}
{时间}:表示滚动的时候所存留的时间,一次请求的会话时间。

{
    "query": {
        "match_all": {}
    },
    # 固定"_doc"
    "sort": ["_doc"],
    # 每一次请求的数据量
    "size": 5
}

当出现如下提示,说明会话失效了,需要重新发起第一次调用(第一次的时候设置的1m)

第二次及之后的查询:
http://{IP}:{port}/_search/scroll

{
    "scroll_id": "DnF1ZXJ5VGhlbkZldGNoAwAAAAAAAADeFlE2VkRNSHJjUlhtbjFTOHRDMGxpVHcAAAAAAAAA4BZRNlZETUhyY1JYbW4xUzh0QzBsaVR3AAAAAAAAAN8WUTZWRE1IcmNSWG1uMVM4dEMwbGlUdw==",
    "scroll": "1m"
}


当请求回来的"hits"是一个空数组,那就说明数据已经都查询完毕了。

如果设置的size为1000,但是有可能取到超过这个值数量的文档。因为查询的时候,size作用于单个分配,所以实际返回的文档最大数是 size * 分片数。

_mget批量查询

除了使用ids查询方式,还有_mget

POST:http://{IP}:{port}/{索引名称}/_doc/_mget

与ids查询的区别:
  1. ids查询更偏向于分页搜索,返回的元数据中包含分页的一些信息,而mget返回的元数据就是按照查询的条件来进行返回;
  2. ids查询中如果查询3个id,但是有一个没有查询到,那么就只返回2条记录,并不知道哪个没有匹配到;但是mget返回的数据中有一个found标记,表示这个条件的数据有没有查询到。

批量操作bulk

bulk操作和其他的基本操作不同,bulk不需要使用json格式化。

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

action: 表示操作的类型,新增、修改、删除。
metadata : 需要操作的文档的 _index 、 _type 和 _id , _index 、 _type 也可以在url中指定。
\n: 每行结尾都需要有\n,这是es的一个解析规范。
{ request body }: 请求体,新增、修改需要有,删除可以不用。

action有以下类型:
create:文档不存在,就会创建;如果文档存在就会报错,但是报错不影响其他操作。
index:创建一个新文档或者替换一个现有的文档。
update:部分更新一个文档。
delete:删除一个文档。

create

POST:http://{IP}:{port}/_bulk

{"create":{"_index":"shop2","_type":"_doc","_id":"8888"}}
{"id":"8888","nickname":"name-8888"}
{"create":{"_index":"shop2","_type":"_doc","_id":"9999"}}
{"id":"9999","nickname":"name-9999"}


index

POST:http://{IP}:{port}/{索引名称}/_doc/_bulk

{"index":{"_id":"6666"}}
{"id":"6666","nickname":"name-6666"}
{"index":{"_id":"7777"}}
{"id":"7777","nickname":"name-7777"}


update

POST:http://{IP}:{port}/{索引名称}/_doc/_bulk

{"update":{"_id":"6666"}}
{"doc":{"id":"6655"}}
{"update":{"_id":"7777"}}
{"doc":{"id":"77777","nickname":"777777"}}


delete
{"delete":{"_id":"6666"}}
{"delete":{"_id":"7777"}}


数据就已经被删除了

批量请求数据体量说明

bulk文档

相关实践学习
使用阿里云Elasticsearch体验信息检索加速
通过创建登录阿里云Elasticsearch集群,使用DataWorks将MySQL数据同步至Elasticsearch,体验多条件检索效果,简单展示数据同步和信息检索加速的过程和操作。
ElasticSearch 入门精讲
ElasticSearch是一个开源的、基于Lucene的、分布式、高扩展、高实时的搜索与数据分析引擎。根据DB-Engines的排名显示,Elasticsearch是最受欢迎的企业搜索引擎,其次是Apache Solr(也是基于Lucene)。 ElasticSearch的实现原理主要分为以下几个步骤: 用户将数据提交到Elastic Search 数据库中 通过分词控制器去将对应的语句分词,将其权重和分词结果一并存入数据 当用户搜索数据时候,再根据权重将结果排名、打分 将返回结果呈现给用户 Elasticsearch可以用于搜索各种文档。它提供可扩展的搜索,具有接近实时的搜索,并支持多租户。
相关文章
|
1月前
|
SQL JSON 大数据
ElasticSearch的简单介绍与使用【进阶检索】 实时搜索 | 分布式搜索 | 全文搜索 | 大数据处理 | 搜索过滤 | 搜索排序
这篇文章是Elasticsearch的进阶使用指南,涵盖了Search API的两种检索方式、Query DSL的基本语法和多种查询示例,包括全文检索、短语匹配、多字段匹配、复合查询、结果过滤、聚合操作以及Mapping的概念和操作,还讨论了Elasticsearch 7.x和8.x版本中type概念的变更和数据迁移的方法。
ElasticSearch的简单介绍与使用【进阶检索】 实时搜索 | 分布式搜索 | 全文搜索 | 大数据处理 | 搜索过滤 | 搜索排序
|
2天前
|
存储 缓存 自然语言处理
深度解析ElasticSearch:构建高效搜索与分析的基石
【9月更文挑战第8天】在数据爆炸的时代,如何快速、准确地从海量数据中检索出有价值的信息成为了企业面临的重要挑战。ElasticSearch,作为一款基于Lucene的开源分布式搜索和分析引擎,凭借其强大的实时搜索、分析和扩展能力,成为了众多企业的首选。本文将深入解析ElasticSearch的核心原理、架构设计及优化实践,帮助读者全面理解这一强大的工具。
32 7
|
2月前
|
存储 人工智能 自然语言处理
阿里云Elasticsearch AI场景语义搜索最佳实践
本文介绍了如何使用阿里云Elasticsearch结合搜索开发工作台搭建AI语义搜索。
17240 68
|
1月前
|
人工智能 自然语言处理 搜索推荐
阿里云Elasticsearch AI搜索实践
本文介绍了阿里云 Elasticsearch 在AI 搜索方面的技术实践与探索。
18803 20
|
8天前
|
JSON 自然语言处理 算法
ElasticSearch基础2——DSL查询文档,黑马旅游项目查询功能
DSL查询文档、RestClient查询文档、全文检索查询、精准查询、复合查询、地理坐标查询、分页、排序、高亮、黑马旅游案例
ElasticSearch基础2——DSL查询文档,黑马旅游项目查询功能
因为一个问题、我新学了一门技术 ElasticSearch 分布式搜索
这篇文章讲述了作者因为一个检索问题而学习了ElasticSearch技术,并分享了排查和解决ElasticSearch检索结果与页面展示不符的过程。
因为一个问题、我新学了一门技术 ElasticSearch 分布式搜索
|
19天前
|
JSON 监控 Java
Elasticsearch 入门:搭建高性能搜索集群
【9月更文第2天】Elasticsearch 是一个分布式的、RESTful 风格的搜索和分析引擎,基于 Apache Lucene 构建。它能够处理大量的数据,提供快速的搜索响应。本教程将指导你如何从零开始搭建一个基本的 Elasticsearch 集群,并演示如何进行简单的索引和查询操作。
59 3
|
2月前
|
数据采集 人工智能 安全
阿里云Elasticsearch 企业级AI搜索方案发布
本文从AI搜索落地的挑战、阿里云在RAG场景的实践、效果提升三个方面,深度解读阿里云Elasticsearch 企业级AI搜索方案。
317 8
|
24天前
|
存储 人工智能 安全
保障隐私的Elasticsearch AI搜索解决方案
【8月更文第28天】随着大数据和人工智能技术的发展,搜索引擎在日常生活中扮演着越来越重要的角色。然而,用户隐私保护成为了一个不容忽视的问题。本文将探讨如何在确保用户数据隐私的同时,利用Elasticsearch实现智能搜索功能。我们将介绍一种综合方案,该方案结合了加密技术、差分隐私、匿名化处理以及安全多方计算等方法,以保障用户数据的安全性
57 0
|
1月前
|
数据采集 人工智能 自然语言处理
阿里云Elasticsearch AI语义搜索:解锁未来搜索新纪元,精准洞察数据背后的故事!
【8月更文挑战第2天】阿里云Elasticsearch AI场景语义搜索最佳实践
117 5