Elasticsearch翻译 elasticsearch句子查询
你现在阅读的是一篇关于Elasticsearch翻译的文章,里面有丰富多彩的内容,还有给你准备elasticsearch句子查询和Elasticsearch翻译的精彩内容哦。
Elasticsearch翻译 elasticsearch句子查询
文本分析是将非结构化文本(例如电子邮件的正文或产品说明)转换为针对搜索优化的结构化格式的过程。何时配置文本分析
当索引或搜索text字段时,Elasticsearch执行文本分析。
如果索引不包含text字段,则无需进一步设置;您可以跳过本节中的页面。
但是,如果您使用text字段或文本搜索未返回预期的结果,则配置文本分析通常会有所帮助。如果您正在使用Elasticsearch执行以下操作,则还应该研究分析配置:
- 建立一个搜索引擎
- 矿山非结构化数据
- 优化搜索特定语言
- 进行词典或语言研究
文字分析概述
文本分析使Elasticsearch能够执行全文搜索,其中搜索返回所有相关结果,而不仅仅是精确匹配。
如果要搜索Quick fox jumps,则可能需要包含的文档,A quick brown fox jumps over the lazy dog也可能需要包含诸如fast fox或的相关单词的文档foxes leap。
代币化
通过令牌化,分析使全文搜索成为可能:将文本分解为较小的块,称为令牌。在大多数情况下,这些标记是单个单词。
如果您将该词组索引the quick brown fox jumps为单个字符串,并且用户搜索quick fox,则不会将其视为匹配项。但是,如果您对词组进行标记并分别索引每个词,则可以单独查询查询字符串中的词。这意味着他们可以通过搜索进行匹配quick fox,fox brown或其他变化。
正常化
令牌化可以根据单个条件进行匹配,但是每个令牌仍在字面上进行匹配。这意味着:
- 即使您可能希望一个字词与另一个字词Quick匹配quick,也 不会进行 搜索
- 尽管fox和foxes共享相同的词根,但搜索foxes 将不匹配fox,反之亦然。
- 搜索jumps将不匹配leaps。尽管它们不共享根词,但它们是同义词,并且具有相似的含义。
为了解决这些问题,文本分析可以将这些标记标准化为标准格式。这样,您就可以匹配与搜索字词不完全相同但足够相似且仍然相关的令牌。例如:
- Quick可以小写:quick。
- foxes可以词干或简化为词根:fox。
- jump并且leap是同义词,可以将其索引为一个单词:jump。
为确保搜索词按预期与这些单词匹配,您可以将相同的标记化和规范化规则应用于查询字符串。例如,Foxes leap可以将搜索标准化为搜索fox jump。
自定义文本分析
文本分析由分析器执行,它是控制整个过程的一组规则。
Elasticsearch包含一个默认的分析器,称为 标准分析器,它在开箱即用的情况下适用于大多数用例。
如果要定制搜索体验,则可以选择其他 内置分析仪,甚至可以 配置自定义分析仪。定制分析器使您可以控制分析过程的每个步骤,包括:
- 标记化之前对文本的更改
- 文本如何转换为令牌
- 在索引或搜索之前对令牌进行规范化更改
分析仪的解剖
的分析?-无论是内置或自定义-只要是包含三个低级别的积木包:字符过滤器,断词和记号过滤。
内置的分析器将这些构件预先打包到适合于不同语言和文本类型的分析器中。Elasticsearch还公开了各个构建基块,以便可以将它们组合以定义新的custom分析器。
字符过滤器
甲字符过滤器接收原始文本字符的流,并且可以通过添加,移除,或改变字符变换流。例如,可以使用字符过滤器将印度-阿拉伯数字(????????)转换为其等效的阿拉伯-拉丁语(0123456789),或<b>从流中剥离HTML元素。
分析器可能具有零个或多个 按顺序应用的字符过滤器。
分词器
甲标记生成器接收字符流,其分成单个令牌(通常单个单词),并且输出流的令牌。例如,whitespace令牌生成器在看到任何空格时都会将文本分成令牌。它将把文本 "Quick brown fox!"转换成术语[Quick, brown, fox!]。
分词器还负责记录每个术语的顺序或位置以及该术语表示的原始单词的开始和结束字符偏移量。
分析器必须恰好 具有一个标记器。
令牌过滤器
甲令牌滤波器接收到令牌流,并且可以添加,删除或改变令牌。例如,lowercase令牌过滤器将所有令牌转换为小写字母, stop令牌过滤器从令牌流中删除常见词(停用词)the,然后 synonym令牌过滤器将同义词引入令牌流。
令牌过滤器不允许更改每个令牌的位置或字符偏移量。
分析器可能具有零个或多个 按顺序应用的令牌过滤器。
索引和搜索分析
文本分析发生两次:
索引时间
索引文档后,text将分析所有字段值。
搜索时间
在字段上进行全文搜索时text,将分析查询字符串(用户正在搜索的文本)。
搜索时间也称为查询时间。
每次使用的分析器或一组分析规则分别称为索引分析器或搜索分析器。
索引和搜索分析器如何协同工作
在大多数情况下,应在索引和搜索时使用同一台分析仪。这样可以确保将字段的值和查询字符串更改为相同形式的标记。反过来,这可以确保令牌在搜索过程中符合预期。
例
在text字段中使用以下值索引文档:
在敏捷的棕色狐狸跳过了狗!
字段的索引分析器将值转换为令牌并对其进行规范化。在这种情况下,每个标记都代表一个词:
[快速,棕色,狐狸,跳跃,跳过,狗]
这些索引然后被索引。
稍后,用户在同一text字段中搜索:
“狐狸”
用户期望此搜索与之前索引的句子匹配 The QUICK brown foxes jumped over the dog!。
但是,查询字符串不包含文档原始文本中使用的确切单词:
- quick 与 QUICK
- fox 与 foxes
为了解决这个问题,使用相同的分析器分析查询字符串。该分析器产生以下令牌:
[快,狐狸]
为了执行搜索,Elasticsearch将这些查询字符串标记与text字段中索引的标记进行比较。
代币 | 请求参数 | text 领域 |
quick | X | X |
brown | X | |
fox | X | X |
jump | X | |
over | X | |
dog | X |
因为字段值和查询字符串的分析方法相同,所以它们创建了相似的标记。标记quick和fox是完全匹配。这意味着搜索与"The QUICK brown foxes jumped over the dog!"用户期望的匹配包含的文档。
何时使用其他搜索分析器
尽管不那么常见,但有时在索引和搜索时使用不同的分析器是有意义的。为此,Elasticsearch允许您 指定一个单独的搜索分析器。
通常,仅当对字段值使用相同形式的标记时,才应指定单独的搜索分析器,并且查询字符串会创建意外或不相关的搜索匹配项。
例
Elasticsearch用于创建仅与以提供的前缀开头的单词匹配的搜索引擎。例如,搜索tr应返回tram或 trope-但从不返回taxi或bat。
文档被添加到搜索引擎的索引中;该文档在一个text字段中包含一个这样的词:
“apple”
字段的索引分析器将值转换为令牌并对其进行规范化。在这种情况下,每个标记都表示该词的潜在前缀:
[ a ,ap ,app ,appl ,apple ]
这些索引然后被索引。
稍后,用户在同一text字段中搜索:
“ appli”
用户希望此搜索仅匹配以开头的单词appli,例如appliance或application。搜索不匹配apple。
但是,如果使用索引分析器来分析此查询字符串,它将产生以下标记:
[ a ,ap ,app ,appl ,appli ]
当Elasticsearch将这些查询字符串标记与为索引的标记进行比较时apple,它会找到多个匹配项。
代币 | appli | apple |
a | X | X |
ap | X | X |
app | X | X |
appl | X | X |
appli | X |
这意味着搜索将错误地匹配apple。不仅如此,它还可以匹配以开头的任何单词a。
要解决此问题,您可以为该text字段上使用的查询字符串指定其他搜索分析器。
在这种情况下,您可以指定一个搜索分析器,该分析器生成一个令牌而不是一组前缀:
[应用]
此查询字符串标记将仅与以开头的单词的标记匹配 appli,从而更好地符合用户的搜索期望。
词干
词干是将单词还原为词根形式的过程。这样可以确保在搜索过程中单词匹配的变体。例如,walking和walked可以被词干为同一个词根: walk。词干一旦词干出现,就会在搜索中匹配另一个词。
词干依赖于语言,但通常涉及从单词中删除前缀和后缀。
在某些情况下,词干的词根形式可能不是真实词。例如,jumping和jumpiness都可以作为jumpi。虽然jumpi 不是真正的英语单词,但搜索无关紧要。如果将单词的所有变体都简化为相同的词根形式,则它们将正确匹配。
词干令牌过滤器编辑
在Elasticsearch中,词干由词干令牌过滤器处理。这些令牌过滤器可以根据其词干的方式进行分类:
- 算法词干分析器,它基于一组规则来 词干
- 字典词干,通过在字典中查找来 词干
由于词干会更改令牌,因此我们建议在索引和搜索分析期间使用相同的词干令牌过滤器。
算法词干编辑
算法词干对每个单词应用一系列规则,以将其简化为词根形式。例如,英语的算法词干可以从复数单词的末尾删除-s 和-es后缀。
算法词干有一些优点:
- 他们需要很少的设置,并且通常开箱即用。
- 他们使用很少的内存。
- 它们通常比字典词干分析器快。
但是,大多数算法词干仅会更改单词的现有文本。这意味着它们可能不适用于不包含其词根形式的不规则单词,例如:
- be,are和am
- mouse 和 mice
- foot 和 feet
以下令牌过滤器使用算法词干:
- stemmer,它提供了几种语言的算法词干,其中一些带有其他变体。
- kstem,是英语的词干分析器,它将算法词干与内置词典结合在一起。
- porter_stem,是我们推荐的英语算法提取器。
- snowball,它对几种语言使用 基于Snowball的词干规则。
字典词干编辑
字典词干查找提供的字典中的词,用字典中的词干词替换未阻止的词变体。
从理论上讲,字典词干非常适合:
- 阻止不规则单词
- 辨别拼写相似但概念上不相关的单词,例如:organ 和 organizationbroker 和 broken
在实践中,算法词干分析器通常优于字典词干分析器。这是因为字典词干提取器具有以下缺点:
- 词典质量词典词干分析器仅与其词典一样好。为了运作良好,这些词典必须包含大量单词,并定期更新并随语言趋势而变化。通常,当提供字典时,它是不完整的,并且其某些条目已经过时了。
- 大小和性能词典词干必须将其词典中的所有单词,前缀和后缀加载到内存中。这会占用大量RAM。低质量词典在删除前缀和后缀时也可能效率较低,这会大大减慢词干的处理速度。
您可以使用hunspell令牌过滤器执行字典词干。
如果可用,我们建议您在使用hunspell令牌过滤器之前尝试针对您的语言的算法词干分析器。
控制词干编辑
有时,词干可以产生共享的根词,这些词的拼写相似但在概念上不相关。例如,词干提取器可以将skies和 都减少skiing为相同的词根:ski。
为了防止这种情况并更好地控制词干,可以使用以下令牌过滤器:
- stemmer_override,可让您定义用于阻止特定令牌的规则。
- keyword_marker,将指定的标记标记为关键字。关键字令牌不会被后续的词干令牌过滤器阻止。
- conditional,可用于将标记标记为关键字,类似于keyword_marker过滤器。
对于内置语言分析器,您还可以使用 stem_exclusion参数来指定不会被词干限制的单词列表。
令牌图
当令牌生成器将文本转换为令牌流时,它还会记录以下内容:
- 的position流中的每个标记的
- 的positionLength,位置是令牌的跨距数
使用这些,您可以为流创建一个有 向无环图,称为令牌图。在令牌图中,每个位置代表一个节点。每个标记都表示指向下一个位置的边或弧。
同义词编辑
一些令牌过滤器可以将新的令牌(例如同义词)添加到现有令牌流中。这些同义词通常与现有标记的位置相同。
在下图中,quick其同义词fast都具有的位置 0。它们跨越相同的位置。
多位置代币编辑
一些令牌过滤器可以添加跨多个位置的令牌。这些可以包括用于多词同义词的令牌,例如使用“ atm”作为“自动柜员机”的同义词。
但是,只有某些令牌过滤器(称为图形令牌过滤器)positionLength才能准确记录多位置令牌。此过滤器包括:
- synonym_graph
- word_delimiter_graph
在下面的图形domain name system及其同义词中dns,两者的位置均为0。然而,dns有一个positionLength的3。图中的其他标记的默认positionLength值为1。
使用令牌图进行搜索编辑
索引将忽略该positionLength属性,并且不支持包含多位置标记的标记图。
但是,查询(例如match或 match_phrase查询)可以使用这些图从单个查询字符串生成多个子查询。
例
无效的令牌图编辑
以下令牌过滤器可以添加跨多个位置但仅记录默认值positionLength的令牌1:
- synonym
- word_delimiter
这意味着这些过滤器将为包含此类令牌的流生成无效的令牌图。
在下图中,dns是的多位置同义词domain name system。但是,dns默认positionLength值为1,导致图形无效。
避免使用无效的令牌图进行搜索。无效的图形可能会导致意外的搜索结果。
相思之苦的经典句子(真的想你)
好想附在你的耳畔,轻声告诉你,我好想你,一别成殇,对你的惦记从未放下。
好想,踏一缕清风,轻轻走进你的世界里,看看你的样子,听听你的声音,向你诉说我一往而深的痴迷。
一份爱,还似从前一般深挚,却只能以一种寂寞的方式静默无语。
自你离去,我掩藏了所有痴心的话语,无声无息的爱着你。
那些说不出的爱恋,都压抑在心底,你不来,爱就是一辈子静默无声的秘密。
想你,念你,圈地为牢恋你,执迷不悟念你,我爱你
时光一日一日,一年一年,在悄无声息中流逝。
逝水流年,漂浅了太多记忆,却未曾让我放下你,一遇倾心,一生爱你,一朝别离,一世想你。
你离开后,我为自己筑起一座心牢,将你的记忆长锁在我的心牢里,别人走不进来,我也不舍得将你忘记。
为你执迷不悟,是我自己愿意,哪怕相思再苦,我也甘之若饴。
有幸遇见你,深深爱着你,无论你在哪里,你都是我心中最特别的存在,今生缘分断了,还有相思情牵。
亲爱的,我爱你!这一句我爱你,今生今世,我只说给你。
曲终人散,人去念依然
听过世间最无奈的话语:
蝴蝶为花碎,花却随风飞,花舞花落泪,花落为谁悲。
蝶恋花,为花醉,为花舞,奈何,花却随风飞,为风痴,为风悲。
世间情缘又何尝不是如此,深爱之人未必能够相守,情深至极未必可以相依。
感慨,今生情深缘浅,无缘与最深爱的你相依相伴,那缘曲终人散,对你的深情却留在心间,一念情深,一生沉沦。
为你,我倾尽了世间最真的爱,为你,我流过了今生最无奈的眼泪。
明明知道,若是缘分散了,思念还在,眉间心上的思念会苦了自己,可偏偏想你总是心不由己,爱你总是情难自抑。
我真的爱你,断了情缘,断不开思念,曲终人散,人去念依然。
真的想你,寄一封信给你,心中满满都是我的思念
想你,念你,却不能去看看你,因为我怕,怕我的冒昧会带给你困扰。
爱你,恋你,却不能打电话给你,因为我怕,怕我会压抑不住内心涌动的相思。
相思的话语不能说,对你的爱恋放不下,情深痴痴,痴念深深,只能深深地压抑在自己心底,藏成心底最深的秘密。
我的秘密就是想你,一个人孤单地想,寂寞的念,在风中想,在月下念,春来的时候想,秋尽的时候念……。
想你,想你,想你,想你,我以为我能忘记你,却要用整整一个余生去想你。
想你,想你,想你,想你,我以为我能不想你,却发现,“晓看天色暮看云,行也是你,坐也是你”。
用心爱过的人,就算无缘夫妻,也会在心里铭记一辈子;走进心中的爱,就算不能再相见,也会在梦中续写爱的永远。
亲爱的,我真的想你,真的真的好想你,寄一封信给最爱的你,信中满满都是我对你的相思。
想你,念你,就算今生不能朝朝暮暮,你也是我永恒的相思。
免费英语句子分析器(ElasticSearch原理知识点和整体结构详解)
ElasticSearch整体结构
通过上文,在通过图解了解了ES整体的原理后,我们梳理下ES的整体结构
- 一个 ES Index 在集群模式下,有多个 Node (节点)组成。每个节点就是 ES 的Instance (实例)。
- 每个节点上会有多个 shard (分片), P1 P2 是主分片, R1 R2 是副本分片
- 每个分片上对应着就是一个 Lucene Index(底层索引文件)
- Lucene Index 是一个统称由多个 Segment (段文件,就是倒排索引)组成。每个段文件存储着就是 Doc 文档。commit point记录了所有 segments 的信息
补充:Lucene索引结构
上图中Lucene的索引结构中有哪些文件呢?
更多文件类型可参考
文件的关系如下:
补充:Lucene处理流程
上文图解过程,还需要理解Lucene处理流程, 这将帮助你更好的索引文档和搜索文档。
创建索引的过程:
- 准备待索引的原文档,数据来源可能是文件、数据库或网络
- 对文档的内容进行分词组件处理,形成一系列的Term
- 索引组件对文档和Term处理,形成字典和倒排表
搜索索引的过程:
- 对查询语句进行分词处理,形成一系列Term
- 根据倒排索引表查找出包含Term的文档,并进行合并形成符合结果的文档集
- 比对查询语句与各个文档相关性得分,并按照得分高低返回
补充:ElasticSearch分析器
上图中很重要的一项是语法分析/语言处理, 所以我们还需要补充ElasticSearch分析器知识点。
分析 包含下面的过程:
- 首先,将一块文本分成适合于倒排索引的独立的 词条 ,
- 之后,将这些词条统一化为标准格式以提高它们的“可搜索性”,或者 recall
分析器执行上面的工作。 分析器 实际上是将三个功能封装到了一个包里:
- 字符过滤器 首先,字符串按顺序通过每个 字符过滤器 。他们的任务是在分词前整理字符串。一个字符过滤器可以用来去掉HTML,或者将 & 转化成 and。
- 分词器 其次,字符串被 分词器 分为单个的词条。一个简单的分词器遇到空格和标点的时候,可能会将文本拆分成词条。
- Token 过滤器 最后,词条按顺序通过每个 token 过滤器 。这个过程可能会改变词条(例如,小写化 Quick ),删除词条(例如, 像 a, and, the 等无用词),或者增加词条(例如,像 jump 和 leap 这种同义词)。
Elasticsearch提供了开箱即用的字符过滤器、分词器和token 过滤器。 这些可以组合起来形成自定义的分析器以用于不同的目的。
内置分析器
Elasticsearch还附带了可以直接使用的预包装的分析器。接下来我们会列出最重要的分析器。为了证明它们的差异,我们看看每个分析器会从下面的字符串得到哪些词条:
"Set the shape to semi-transparent by calling set_trans(5)"
- 标准分析器
标准分析器是Elasticsearch默认使用的分析器。它是分析各种语言文本最常用的选择。它根据 Unicode 联盟 定义的 单词边界 划分文本。删除绝大部分标点。最后,将词条小写。它会产生
set, the, shape, to, semi, transparent, by, calling, set_trans, 5
- 简单分析器
简单分析器在任何不是字母的地方分隔文本,将词条小写。它会产生
set, the, shape, to, semi, transparent, by, calling, set, trans
- 空格分析器
空格分析器在空格的地方划分文本。它会产生
Set, the, shape, to, semi-transparent, by, calling, set_trans(5)
- 语言分析器
特定语言分析器可用于 很多语言。它们可以考虑指定语言的特点。例如, 英语 分析器附带了一组英语无用词(常用单词,例如 and 或者 the ,它们对相关性没有多少影响),它们会被删除。 由于理解英语语法的规则,这个分词器可以提取英语单词的 词干 。
英语 分词器会产生下面的词条:
set, shape, semi, transpar, call, set_tran, 5
注意看 transparent、 calling 和 set_trans 已经变为词根格式。
什么时候使用分析器
当我们 索引 一个文档,它的全文域被分析成词条以用来创建倒排索引。 但是,当我们在全文域 搜索 的时候,我们需要将查询字符串通过 相同的分析过程 ,以保证我们搜索的词条格式与索引中的词条格式一致。
全文查询,理解每个域是如何定义的,因此它们可以做正确的事:
- 当你查询一个 全文 同时, 会对查询字符串应用相同的分析器,以产生正确的搜索词条列表。
- 当你查询一个 精确值 域时,不会分析查询字符串,而是搜索你指定的精确值。
举个例子
ES中每天一条数据, 按照如下方式查询:
GET /_search?q=2023 # 12 resultsGET /_search?q=2023-09-15 # 12 results !GET /_search?q=date:2023-09-15 # 1 resultGET /_search?q=date:2023 # 0 results !
为什么返回那样的结果?
- date 域包含一个精确值:单独的词条 2023-09-15。
- _all 域是一个全文域,所以分词进程将日期转化为三个词条: 2023, 09, 和 15。
当我们在 _all 域查询 2023,它匹配所有的12条推文,因为它们都含有 2023 :
GET /_search?q=2023 # 12 results
当我们在 _all 域查询 2023-09-15,它首先分析查询字符串,产生匹配 2023, 09, 或 15 中 任意 词条的查询。这也会匹配所有12条推文,因为它们都含有 2023 :
GET /_search?q=2023-09-15 # 12 results !
当我们在 date 域查询 2023-09-15,它寻找 精确 日期,只找到一个推文:
GET /_search?q=date:2023-09-15 # 1 result
当我们在 date 域查询 2023,它找不到任何文档,因为没有文档含有这个精确日志:
GET /_search?q=date:2023 # 0 results !
免费英语句子分析器(电商搜索系统精讲系列三步曲2)
编辑导读:在电商软件中搜索一款产品,页面中会出现很多相关产品的展示。这些页面是如何展示呢?为什么会这样展示?本文作者以电商产品为例,对其页面排序系统进行分析,希望对你有帮助。
01 排序的场景模型
上篇文章我们针对一个电商搜索系统的业务以及召回分析器和模型的分析,比如当用户在淘宝APP搜索框中输入搜索关键词“2023年新款花式促销女士连衣裙”,搜索系统会通过分析器和各种模型来理解用户的搜索意图,进而达到召回商品的目的(这块的原型将在“电商搜索系统精讲系列三步曲”的下篇会push给大家);
那么思考一个问题,用户搜索“2023年新款花式促销女士连衣裙”之后,页面怎么展示,为什么会这么展示?依据是什么,如下图?
这个就是我们今天要去讲的内容,往下看:
在分析这块的内容之前,同样,我依然举现实生活中的场景模型:
某公司产品总监A需要招聘具有丰富教育中台行业经验的产品经理,在BOSS直聘的岗位描述JD(Job Description)增加了要具备教育中台行业的经验的招聘要求,于是有以下求职者去面试:
- 应聘者B:有教育行业经验,但无中台产品建设经验;
- 应聘者C:有教育行业经验,但工作年限比较短,不够丰富;
- 应聘者D:有中台产品建设经验,但无教育行业经验;
- 应聘者E:有丰富的教育中台行业经验,但是之前做的是解决方案,并非产品经理岗;
那么现在,假设你作为该公司的产品总监,你该怎么选?先不要看下面,先思考;
答案其实也很简单,你一定是挑选一个适合该岗位要求的吧,那么什么才叫适合,评判的依据是什么?你作为产品总监究竟怎么对这四个求职者进行评估?
现在有些大公司采购了线上招聘系统,人力资源HR和产品总监把对这四位求职者的面试结论以文字的方式直接录入到这个招聘系统,系统就会给出一个建议分,这个建议分值提供给产品总监和HR人员进行决策评估和参考,当然没有这个线上招聘系统也没关系,最土的办法就是下面这种,用手填写面试评估表,用手打分,只不过这种方式的打分更多带有主观色彩。
所以最后的结论就是对每个求职者进行打分,然后通过打分来对B、C、D、E四名求职者进行排序,排序第一、第二、第三及第四,最后择优录用;
好,上面说的是招聘的工作,想一想,我们每年高考录取是不是也是这种方式来进行择优录取,同样的场景模型,我们尝试搬迁到线上,应用在召回商品的排序上,接着看:
那么问题来了,同样的场景模型搬迁到线上,就会涉及到对召回的商品打分怎么打的问题,这个是核心,人类有大脑可以用于主观判断,但电脑没有眼睛没有感官系统,没法等同于人类那样去思考,所以我们需要做的就是给他输入一系列的打分规则,电脑就能打分,就能对召回的商品进行排序,从而实现我们的目标,接下来我们看排序的策略;
02 排序策略
大家回想之前浙江卫视的中国好声音节目,那些在电视荧幕上看到的唱歌选手也一定是提前开始海选,然后逐层选拔通过才会参加电视上的唱歌比赛吧,如果没有海选这个环节呢,每个人只要报名都可以直接在电视上唱那么一曲,那岂不是要把浙江卫视那些工作人员累死,所以选手是通过海选,逐层比赛,一关一关的通过,最后挑选出表现优秀的前100名参与电视上的唱歌比赛;
我们采用同样的套路,召回的商品(因为这个量级也是非常巨大的)先海选,再去精选,业内很多人称海选为粗选,所以召回的商品先要进行粗选,通过粗选把可能满足用户意图并且是相对优质的商品(比如有一万个)全部筛选出来,再去优化(一万个召回的商品精选排序)这个选择的结果,最后把选出来的前1000(只是假设)个商品进行排序展示给用户;
搜索引擎本身对于检索性能要求比较高,所以需要采用上面说的两个阶段排序过程:粗排和精排。粗排就是上面说的海选,从检索结果中快速找到优质的商品,取出TOP N个结果再按照精排进行打分,最终返回最优的结果给用户。所以一般在搜索系统中,粗排对性能影响比较大,精排对最终排序效果影响比较大,因此,粗排要求尽量简单有效,只提取数据库表中的关键因子(字段)即可,关键的问题在于打分怎么打,下面将给大家介绍常见的打分策略:
我们首先引入一个新的概念—-表达式计算法
所谓表达式计算法:通俗的讲,就是通过不同的计算公式来运算每个被召回的产品和用户意图的相关度,这个相关度某种意义上讲就是打的分数,业内普遍称这个过程为相关算分,一般常见的计算公式比如基本运算(算术运算、关系运算、逻辑运算、位运算、条件运算)、数学函数和排序特征(feature)等。
基本运算:
数学函数:
以上两个函数比较简单,高等数学里面都有的内容,这里不再细说,下面来看下上面提到的粗排常用的几个函数(以下为天猫搜索为例):
关键词相似文本分Text similarity函数:用于计算用户输入的关键词文本与召回的商品相关度,值越大,则相关度越高;
召回商品距离现在的时间GoodsTime函数:用于计算召回的商品距离现在的时间,一般取值为(0,1)之间,一般值越大,表商品距离现在时间越近,越容易被展示在用户的界面;
类目预测函数CategoryPredic:用于计算用户输入的关键词与商品类目的相关度,关于类目预测这里需要仔细说明下:
所谓类目预测,指的是通过计算机的算法去预测搜索的关键词与商品
类目的相关程度,我们举个例子,当用户在淘宝APP搜索框中输入关键词“苹果”,则类目预测会计算商品所属类目与输入的苹果这个关键词的相关度,类目与关键词的相关度越高,商品就获得了越高的排序得分,也就是上文说到的相关算分值就越高,从而这个商品就会排在越前面,借助下面这两张图,就更好理解了:
第一张图:搜索的关键字是“苹果”,既有手机类的商品也有食物类的商品,左图就是典型的没有使用类目预测模型来打分,所以把食物类的苹果也召回并且优先排序在前面,右图是使用后类目预测模型后的打分排序效果;
所以我们在做产品原型设计的时候也要考虑搜索的关键词与商品类目的相关程度,需要在原型的设计里面增加类目预测的模型的设计;
再来回过头看,我前面讲的,排序首选要进行海选也就是粗排,再针对粗排后的商品结果进行精排,粗排已经讲了,精排怎么排?
同样是要通过函数去计算搜索的关键词与商品的相关度,常见的函数有:
文本相关度函数:
- text_relevance: 关键词在字段上的商品匹配度
- field_match_ratio:获取某字段上与查询词匹配的分词词组个数与该字段总词组个数的比值
- query_match_ratio:获取查询词中(在某个字段上)命中词组个数与总词组个数的比值
- fieldterm_proximity: 用来表示关键词分词词组在字段上的紧密程度
- field_length:获取某个字段上的分词词组个数
- query_term_count: 返回查询词分词后词组个数
- query_term_match_count:获取查询词中(在某个字段上)命中文档的词组个数
- field_term_match_count:获取文档中某个字段与查询词匹配的词组个数
- query_min_slide_window:查询词在某个字段上命中的分词词组个数与该词组在字段上最小窗口的比值
地理位置相关性:
- distance: 获取两个点之间的球面距离。一般用于LBS的距离计算。
- gauss_decay,使用高斯函数,根据数值和给定的起始点之间的距离,计算其衰减程度
- linear_decay,使用线性函数,根据数值和给定的起始点之间的距离,计算其衰减程度
- exp_decay,使用指数函数,根据数值和给定的起始点之间的距离,计算其衰减程度
时效性:
- timeliness: 时效分,用于衡量商品的新旧程度,单位为秒
- timeliness_ms: 时效分,用于衡量商品的新旧程度,单位为毫秒
算法相关性:
- category_score:类目预测函数,返回参数中指定的类目字段与类目预测query的类目匹配分
- popularity:人气分,用于衡量物品的受欢迎程度
功能性:
- tag_match: 用于对查询语句和商品做标签匹配,使用匹配结果对商品进行算分加权
- first_phase_score:获取粗排表达式最终计算分值
- kvpairs_value: 获取查询串中kvpairs子句中指定字段的值
- normalize:归一化函数,根据不同的算分将数值归一化至[0, 1]
- in/notin : 判断字段值是否(不)在指定列表中
以上函数大家不用去研究细节,看看函数的中文解释就好,帮助理解和消化,知道精排的算分怎么统计、哪些维度去统计即可,如果依然不理解的,可以跟我一起交流;
说到现在大家一定很好奇,为什么用户最关心的商品热度没有提到,不着急不着急,接下来,我们就要针对搜索热度比较高的商品一般怎么排序,引入一个新的概念—–人气模型;
上面说的类目预测模型是要实时去计算,而人气模型可以在离线的时候进行计算,一般也叫离线计算模型,这种模型也是淘宝和天猫搜索最基础的排序算法模型。
人气模型会计算量化出每个商品的静态质量以及受欢迎的程度的值,这个值称之为商品人气分,最开始人气模型是来自淘宝的搜索业务,但其实这个模型对于其他的搜索场景也有很强的通用性,在非商品搜索场景中通过人气模型也可以计算出被索引的商品的受欢迎程度,比如某个论坛,可以通过人气模型排序搜索比较多的帖子,把这些帖子内容优先展示给用户;
那么对于一个商品而言,这个人气模型究竟怎么计算,毕竟系统的目标是通过这个模型来计算商品的热度,进而打分排序,你说对吧;
一般情况下,人气模型从四个维度去计算分值,具体如下:
第一个维度:实体维度;
比如:商品、品牌、商家、类目等。
第二个维度:时间维度;
比如:1天、3天、7天、14天、30天等。
第三个维度:行为维度;
第四个维度:统计维度;
每个特征从以上4个维度中各取一到两个进行组合,再从历史数据中统计该组合特征最终的特征值:
比如:
- 商品(实体)最近1天(时间)的曝光(行为)量(统计指标);
- 商品所在店铺(实体)最近30天(时间)的销量(行为类型+统计维度)等等。
由以上方法产生的结果数量级,等同于去计算4个维度的笛卡尔积,再对笛卡尔积的算分高低进行排序;
好了,说到现在关于召回的商品排序所采用的算法目前我所了解的就这么多,当然能力有限,有些搜索的细节依然需要进一步去摸索;
03 召回与排序总结
我们来对上一篇文章和今天讲的内容简单的做个总结,当用户在淘宝APP搜索框中输入“2023年新款花式促销女士连衣裙”时,搜索引擎系统首先要去理解用户的意图,理解的方式就是上篇文章提到的分析器,通过对语义的理解、命名实体识别、拼写纠错、停止词模型等手段去理解用户的意图,进而通过这个意图计算机去到后台数据库中检索符合意图的所有商品,当商品被检索出来之后,搜索引擎系统首先要通过各类函数和模型对商品进行粗排,再对粗排的结果进行精排,精排的依据就是上面的函数和模型,当然还有类目预测模型和人气模型,这个就是大概的流程;
依然没有结束,首先来看下面这张图:
想一想,上面左图中的热搜底纹和热搜列表是怎么来的、右图中的下拉提示又是这么出现的?这个就是原计划需要在今天跟大家讲的引导排序内容;
04 预告
题图来自Pexels,基于CC0协议
免费英语句子分析器(阿里大佬私人珍藏的MySQL笔记)
基本架构
MySQL 基本架构示意图如下:
MySQL 大体可以分为两部分:Server 层和存储引擎层(功能跟日常开发中的 Service 层和与 DAO 层有点像,可以对比理解)。
Server 层
主要有连接器(Connector)、查询缓存(Cache)、分析器(Parser)、优化器(Optimizer)和执行器(Executor)等,包括了 MySQL 的大部分核心功能以及所有内置函数(日期、数学和加密函数等),所有跨存储引擎的功能都在这一层实现,例如存储过程、触发器、视图等。
存储引擎层
存储引擎(Storage Engine)层主要负责数据的存储和提取,它是直接和磁盘打交道的,以插件形式存在,例如 InnoDB、MyISAM、Memory 等多种存储引擎。
从 MySQL 5.5.5 开始,InnoDB 成为了默认的存储引擎。
Server 层
连接器
主要功能:跟客户端建立(TCP)连接、获取权限、维持和管理连接。
若用户认证通过,连接器会查询权限列表获取该用户的权限,之后该连接的权限判断都基于此(因此,一个用户建立连接后,即使被修改了权限也不会影响已存在连接的权限,只有重新建立连接后才生效)。
客户端建立连接示例(分别为失败和成功):
# 连接失败(密码错误)$ mysql -uroot -pEnter password:ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)
# 连接成功$ mysql -uroot -pEnter password:Welcome to the MySQL monitor. Commands end with ; or \g.Your MySQL connection id is 7Server version: 5.7.19 MySQL Community Server (GPL)Copyright (c) 2000, 2023, Oracle and/or its affiliates. All rights reserved.Oracle is a registered trademark of Oracle Corporation and/or itsaffiliates. Other names may be trademarks of their respectiveowners.Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.mysql>
进入 MySQL 后可以用如下命令查看连接状态:
# 查看连接状态mysql> show processlist;+----+------+-----------+------+---------+------+----------+------------------+| Id | User | Host | db | Command | Time | State | Info |+----+------+-----------+------+---------+------+----------+------------------+| 6 | root | localhost | NULL | Sleep | 81 | | NULL || 7 | root | localhost | NULL | Query | 0 | starting | show processlist |+----+------+-----------+------+---------+------+----------+------------------+2 rows in set (0.00 sec)
在 Command 列中,Sleep 表示该连接是空闲的。
连接成功后是有超时时间的,若太长时间没有操作会断开连接,由参数 wait_timeout 控制,默认为 8 小时,
查询缓存
主要功能:缓存查询结果。
连接建立之后,就可以进行查询了。
在一个查询语句中,会先到缓存中查询之前是否查询过该语句,若存在则直接返回对应的结果;否则继续执行后面的流程。
PS: 此处理流程可以类比我们在项目中使用 Redis 等作为缓存的操作,即先查缓存,再查 DB。
也可以通过使用 SQL_CACHE 显式指定使用查询缓存(这里的 id 并非主键),例如:
SELECT SQL_CACHE * FROM t1 WHERE id=10;
查询缓存的优缺点:
1. 优点:查询命中缓存时效率很高。
2. 缺点:缓存失效非常频繁,只要有对一个表的更新,该表所有的查询缓存都会被清空。
由于上述优缺点,可以发现缓存适用于静态表或更新较少的表,对于更新较频繁的表并不适用。值得一提的是,MySQL 8.0 版本已删除了查询缓存功能,可见该功能比较鸡肋。
分析器
主要功能:对 SQL 语句进行词法分析和语法分析。
1. 词法分析:分词操作,由于我们传递给 MySQL 的 SQL 语句实质上就是一个字符串,MySQL 需要将其拆分成一个个的分词(语法树)并进行识别,例如识别“SELECT”、“UPDATE”等关键字,将 t1 识别为一张表,将 id 识别为一列等。
2. 语法分析:拿到词法分析的结果,并根据语法规则判断 SQL 语句是否合法。若语法错误,则会收到如下错误提示:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ...
优化器
主要功能:优化 SQL 语句。
经过了分析器之后,MySQL 已经知道了我们提交的 SQL 语句是干嘛的。但为了提高执行效率,它并非完全按照我们的 SQL 语句执行,而要进行一系列优化。例如,当表中有多个索引时决定使用哪个索引;多表关联(JOIN)查询时决定表连接的顺序等等。
PS: 有点类似于 JVM 执行 Java 代码时的操作。即,JVM 并非完全按照代码的先后顺序来执行的,它会调整一些代码的执行顺序以提高效率,只是保证最终结果与代码顺序执行的效果一致。
执行器
主要功能:执行 SQL 语句。
MySQL 知道了我们要做什么,并且进行了优化,接下来就要开始执行了。执行之前,会判断你对该表是否有查询的权限,若有权限则继续执行;否则会返回如下错误(这里以 SELECT 操作为例,其他类似):
SELECT command denied to user 'user'@'localhost' for table 't1'
为什么到这一步才进行权限检查呢?
是因为有时候 SQL 语句要操作的表不只是 SQL 字面上的那些(例如触发器要在执行过程中才能确定),因此权限检查在这里进行。
存储引擎
以上述 SELECT 语句为例,执行步骤如下:
1. 调用 InnoDB 引擎接口取 t1 表的第一行,判断 id 是否为 10,若不是则跳过;否则将这一条记录存在结果集中;
2. 调用存储引擎接口读取“下一行”,判断逻辑同步骤 1,直至读取到表的最后一行;
3. 执行器将上述遍历过程中所有满足条件的记录作为结果集返回给客户端。
MySQL 查看所有存储引擎:
mysql> show engines;+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+| Engine | Support | Comment | Transactions | XA | Savepoints |+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+| InnoDB | DEFAULT | Supports transactions, row-level locking, and foreign keys | YES | YES | YES || MRG_MYISAM | YES | Collection of identical MyISAM tables | NO | NO | NO || MEMORY | YES | Hash based, stored in memory, useful for temporary tables | NO | NO | NO || BLACKHOLE | YES | /dev/null storage engine (anything you write to it disappears) | NO | NO | NO || MyISAM | YES | MyISAM storage engine | NO | NO | NO || CSV | YES | CSV storage engine | NO | NO | NO || ARCHIVE | YES | Archive storage engine | NO | NO | NO || PERFORMANCE_SCHEMA | YES | Performance Schema | NO | NO | NO || FEDERATED | NO | Federated MySQL storage engine | NULL | NULL | NULL |+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+9 rows in set (0.00 sec)
其中 Support 表示该引擎是否可用(DEFAULT 表示默认值);Comment 是描述信息;Transactions 表示是否支持事务;XA 表示是否支持分布式事务;Savepoints 表示是否支持回滚。
其中最为常用的就是 InnoDB 引擎,而且它也是默认的。其他常见的还有 MyISAM 和 Memory 引擎,这三种引擎简单对比如下:
MyISAMInnoDBMemory存储限制256TB64TB有事务???索引???锁表锁行级锁表锁外键???
小结
MySQL 的整体架构主要分为两部分:Server 层和存储引擎层。
Server 主要有连接器、查询缓存、分析器、优化器和执行器等,包括了 MySQL 的大部分核心功能以及所有内置函数,所有跨存储引擎的功能都在这一层实现,例如存储过程、触发器、视图等。
存储引擎层:负责数据的存储和提取,以插件形式存在,例如 InnoDB (MySQL 5.5.5 以后默认的存储引擎)、MyISAM、Memory 等多种存储引擎。
PS: 发现一个现象,许多东西在学的时候觉得不难,但是如果自己不去做笔记的话就很容易忘记。因此就需要用自己的语言去表达出来,这样更能促进思考,也能进一步“内化”到自己的知识体系中。
索引
简单来说,索引的出现是为了提高查询效率,就像书的目录一样。MySQL 的索引是在「存储引擎」层实现的,因此没有统一的标准,同一种类型的索引,在不同存储引擎之间实现可能也不同。本文主要分析 InnoDB 存储引擎的索引结构。
索引模型
索引模型就是索引的实现形式(也可以理解为索引的数据结构),常见的索引模型有下面三种:
1. 哈希表(散列表)
键值对形式(类似 Java 中的 HashMap)
优点:新增速度快;
缺点:无序,区间查询速度很慢(全表扫描)。
适用场景:只有等值查询的情况(例如 Memcached 等一些 NoSQL 引擎)。
2. 有序数组
优点:等值查询和范围查询速度都很快。
缺点:更新成本太高(插入的记录在中间时,需要移动后面的所有记录,可类比在数组中间位置插入元素的操作)。
适用场景:静态存储引擎(比如不再修改的历史数据)。
3. 搜索树(N 叉树)
优点:读写快,适配磁盘的访问模式。
B+ 树就是其中的一种,也是 InnoDB 存储引擎的索引模型。
InnoDB 记录的存储结构
数据页
在 InnoDB 引擎中,会将数据划分为若干个「页」,「页」是磁盘和内存之间交互的基本单位,页的大小一般为 16KB。即:一般情况下,一次最少从磁盘中读取 16KB 的数据到内存中,一次至少把内存中 16KB 的数据刷新到磁盘中。
向一个数据页中插入记录的过程如图所示:
数据页中分为几个部分,其中 User Records 部分为存储记录的空间(其他部分存储数据页的其他信息,这里暂不详述),插入过程大致如下:
1. 未插入记录时,User Records 部分不存在;
2. 当插入记录时,会从 Free Space 部分划分出空间存储记录;
3. 当 Free Space 空间用完时,也就是该数据页的空间用完了,需要分配新的数据页存储(页分裂)。
记录的结构
在 InnoDB 引擎中,一条记录的存储结构如图所示:
PS: 其中橙色部分 (c1, c2, c3) 是表中的列,且 c1 为主键,下图亦是如此。
也就是说,数据页中记录的数据,除了一条记录本身,还有变长字段列表、NULL 值列表、记录头信息等其他信息,这样才是在数据页中的一条完整记录。
数据页中多条记录之间的关系示意图:
即,每个页中保存了许多条记录,并且每条记录指向下一条记录(根据主键顺序,类似单链表结构)。此外还记录了该页中的最小和最大记录(也是根据主键顺序)。
不仅如此,这些记录还会几条(1~8)分为一个组,并且把组内最大的主键值提取到一个槽(slot)中,用来实现快速(二分)查找,示意图如下:
页内查找记录
以上面的数据页为例,若要查找主键值为 5 的记录,过程如下(二分查找):
1. 计算中间槽的位置:(0+4)/2=2,因此查找槽 2,而它对应记录的主键为 8,5<8,重新计算;
2. 重新计算,(0+2)/2=1,查找槽 1,对应记录的主键值为 4,5>4,因此查找的记录在槽 2 中;
3. 遍历槽 2 对应的分组,查找主键为 5 的记录。
因此在一个数据页中查找指定主键值的记录过程大致分为两步:
1. 通过二分查找确定记录所在的槽;
2. 遍历该槽所在组中的各个记录(通过记录的 next_record)。
由于槽内数据很少(不超过 8 条),因此遍历的成本较低。
聚簇索引&二级索引
根据叶子节点的内容,索引类型可分为「聚簇索引」(Clustered Index)和「二级索引」(Secondary Index)。
1. 聚簇索引
在 InnoDB 存储引擎中,聚簇索引也称为「主键索引」,表都是根据主键顺序组织存放的,这种存储方式的表称为索引组织(Index Organized Table)表(索引即数据,数据即索引)。一张表只能有一个主键索引。
聚簇索引的示意图如下(该结构就是一棵 B+ 树):
图中结构分为三层,其中上面的两层(即非叶子节点,页 33、页 30 和页 32)为索引层,保存的是索引信息;第三层(叶子节点)为数据层。在主键索引中,叶子节点保存的是完整的记录(以数据页为单位)。
PS: 存储节点的空间可能是不连续的,但是,同一层的节点是有前后顺序的,它们之间以「双向链表」的形式连接。
在索引树中查找一条记录的大致过程如下(仍以查找主键值为 5 的记录为例):
1. 先查找根节点,即页 33,页 30 中的主键范围是 [1, 320),而页 32 中主键大于等于 320,因此定位到 页 30;
2. 再查找页 30,同样的方法定位到页 28;
3. 根据上面「页内查找记录」的方式在页 28 中查找。
2. 二级索引
InnoDB 中,二级索引的叶子节点存储的是主键的值。二级索引也称为「非聚簇索引」、「非主键索引」。一张表可以有多个二级索引。其中,以单列作为二级索引的又称「单列索引」,以多列作为索引的又称「联合索引」或者「组合索引」。
二级索引的示意图如下:
该结构与聚簇索引类似,也是一棵 B+ 树。
与聚簇索引的不同之处主要在于第三层,也就是叶子节点,在二级索引中,叶子节点保存的是主键的值。
二级索引中的查找过程与聚簇索引中查找类似。
不同的是,由于二级索引保存的是索引列和主键列,若查找的数据包含索引和主键之外的内容,则需要先找出主键值,然后再根据主键的值到聚簇索引中查找完整记录,该过程称为「回表」。
值得注意的是,上述查找都是在有索引的情况下进行的,如果没有索引呢?则会进行全表扫描,这样当数据量较大时,效率会非常低。这也是索引出现的主要原因。
区别与联系(InnoDB 存储引擎)
1. 聚簇索引和二级索引都需要占用磁盘空间,每一个索引都对应一棵索引树;
2. 二者都是 B+ 树结构,数据都存储在叶子节点(非叶子节点不保存数据);
3. 聚簇索引的叶子节点保存的是完整记录,二级索引保存的是主键的值;
4. 在一张表中,聚簇索引只能有一个,二级索引可以有多个(即多个索引树)。
根据这几点比较也可以发现,索引虽然可以提高查找效率,但也有缺点。如果有多个索引,当修改数据时索引也要同步进行更新,这样会降低操作的效率;而且索引也会占用磁盘空间。因此,索引并非越多越好。
InnoDB 引擎主键选择
在 InnoDB 中,每张表都有个主键(Primary Key),如果在建表时没有显式地定义主键,则 InnoDB 引擎会按照如下方式选择或创建主键:
1. 首先判断表中是否有非空的唯一索引(Unique NOT NULL),若有,则该列即为主键(当表中有多个非空唯一索引时,InnoDB 存储引擎将选择建表时第一个定义的非空唯一索引为主键);
2. 若不符合上述条件,InnoDB 存储引擎自动创建一个 6 字节大小的隐藏列(row_id)作为主键。
因此,建表时最好显式指定主键。
索引优缺点
主要优缺点如下(可通过上述存储结构分析理解):
优点
1. 可以提高数据检索效率,降低数据库 IO 成本;
2. 对记录进行排序,降低 CPU 消耗(被索引的列会自动进行排序),可以提高排序和分组查询的效率。
缺点
1. 索引会占用磁盘空间;
2. 降低更新效率(更新操作会同步更新索引)。
索引使用场景
需要创建索引的场景
1. 主键自动建立唯一索引;
2. 频繁作为查询条件的字段应该创建索引;
3. 多表关联查询中,关联字段应该创建索引(ON 两边都要创建);
4. 查询中排序的字段,应该创建索引;
5. 统计或者分组。
不需要使用索引的场景
1. 表记录太少;
2. 频繁更新;
3. 查询字段使用频率不高。
PS: 这里只是概括了一些常见的优缺点和使用场景,可以根据前面对索引的结构和特点的分析对比理解。
小结
简单来说,索引可以理解为书的目录。
索引的主要作用是为了提高查找效率;但索引也有缺点,并非越多越好,需要根据实际情况决定如何创建合适的索引。
以上内容是关于Elasticsearch翻译和elasticsearch句子查询的内容,小编幸苦为你编辑整理,喜欢的请点赞收藏把。