Press "Enter" to skip to content

掌握Elasticsearch:强大搜索和精确性的入门指南-第1部分

掌握Elasticsearch:强大搜索和精确性的入门指南-第1部分 四海 第1张

目录

· 介绍· Elasticsearch ▪ 样本数据集了解ElasticSearch查询理解响应基本搜索查询· 词法搜索· 当前搜索查询中的问题类似词返回不同结果不理解用户需求不返回类似词忽略拼写错误不同单词组合有不同的含义· 改进我们的搜索提升更相关的字段基于函数提升模糊查询· 结论

介绍

你是否曾想过如何轻松在线找到完美的鞋子,或者在社交媒体的浩瀚世界中偶然看到朋友的帖子?这都要归功于数字体验中的无名英雄:搜索系统。

回想一下你最近的在线购物经历——无论是时尚的一双鞋子还是为朋友挑选的一本深思熟虑的书,你是如何找到确切的目标的?很可能你通过搜索栏穿越了一片选择的海洋!这就是搜索系统的神奇之处,它悄然塑造了我们的在线体验,使我们在数字走廊中轻松发现完美的物品。在充满选择的世界中,能够快速而轻松地找到我们想要的东西,这证明了对于我们喜爱的产品来说,强大而直观的搜索系统的重要性。

在我最近的Elasticsearch探索中(查看我关于其架构和术语的入门文章),我们揭示了这些发现背后的引擎。本文深入研究了搜索——导航ElasticSearch查询,理解响应,并构建一个基本查询来铺垫。

我们的目标是构建一个简单的搜索查询,找出问题,并通过实际示例进行改进。加入我们,认识我们当前搜索系统中的挑战,并在数字走廊的世界中探索推进的路径。

从我们上次离开的地方开始,Elasticsearch

示例数据集

为了演示我们可以改进搜索的不同方式,让我们设置Elasticsearch并加载一些数据。在本文中,我将使用我在Kaggle上找到的这个新闻数据集。数据集很简单,包含约210,000篇新闻文章,包括标题、简要描述、作者和一些我们不太关注的其他字段。我们实际上不需要所有210,000个文档,所以我将在ES中加载大约10,000个文档并开始搜索。

以下是数据集中的几个文档示例:

[  {    "link": "https://www.huffpost.com/entry/new-york-city-board-of-elections-mess_n_60de223ee4b094dd26898361",    "headline": "为何纽约市选举委员会一团糟",    "short_description": "“选举委员会存在根本性问题,”纽约选举律师说。",    "category": "政治",    "authors": "Daniel Marans",    "country": "IN",    "timestamp": 1689878099  },  ....]

每个文档代表一篇新闻文章。每篇文章包含一个link,一个headline,一个short_description,一个categoryauthorscountry(我添加的随机值),以及timestamp(再次是我添加的随机值)。

我添加了countrytimestamp字段,以使下面的示例更有趣,那么让我们开始吧!

了解ElasticSearch查询

Elasticsearch查询是以JSON格式编写的。我们先从简单的开始,逐步构建查询语法。

最简单的全文查询是match查询。其原理很简单,您编写一个查询,Elasticsearch根据指定字段进行全文搜索。例如:

GET news/_search{  "query": {    "match": {      "headline": "抢劫"    }  }}

上述查询找到了所有标题中包含“抢劫”一词的文章。以下是我得到的结果:

{  "_index" : "news",  "_id" : "RzrouIsBC1dvdsZHf2cP",  "_score" : 7.4066687,  "_source" : {    "link" : "https://www.huffpost.com/entry/guard-cat-hailed-as-hero_n_62e9a515e4b00f4cf2352a6f",    "headline" : "被誉为英雄的“守护猫”抢劫未遂后受到赞扬",    "short_description" : "上周,当至少两名人试图闯入密西西比州图普洛市的一所住宅时,这只猫尽其所能警示其主人。",    "category" : "奇闻趣事",    "authors" : "",    "country" : "US",    "timestamp" : 1693070640  }},{  "_index" : "news",  "_id" : "WTrouIsBC1dvdsZHp2wd",  "_score" : 7.4066687,  "_source" : {    "link" : "https://www.huffpost.com/entry/san-francisco-news-crew-security-guard-shot-killed_n_61a2a9d8e4b0ae9a42af278a",    "headline" : "新闻组安保人员在帮助报道抢劫事件时被枪击身亡",    "short_description" : "在有组织的零售犯罪活动增加的背景下,Kevin Nishita在执行任务时被腹部射伤。",    "category" : "犯罪",    "authors" : "Daisy Nguyen, AP",    "country" : "US",    "timestamp" : 1692480894  }}

但是,如果你想对多个字段进行全文搜索怎么办?你可以使用multi_match查询。

GET news/_search{  "query": {    "multi_match": {      "query": "抢劫",      "fields": ["headline", "short_description"]    }  }}

这执行了一个类似的操作,但不再只看一个字段,而是同时查看所有文档的headlineshort_description,并对它们进行全文搜索。

理解响应

这是我们上次查询的示例响应。

{  "took" : 5,  "timed_out" : false,  "_shards" : {    "total" : 1,    "successful" : 1,    "skipped" : 0,    "failed" : 0  },  "hits" : {    "total" : {      "value" : 2,      "relation" : "eq"    },    "max_score" : 29.626675,    "hits" : [      {        "_index" : "news",        "_id" : "RzrouIsBC1dvdsZHf2cP",        "_score" : 29.626675,        "_source" : {          "link" : "https://www.huffpost.com/entry/guard-cat-hailed-as-hero_n_62e9a515e4b00f4cf2352a6f",          "headline" : "无止境抢劫",          "short_description" : "在上周,在密西西比州图佩洛的一所房子里有至少两个人试图闯入,这只猫竭尽所能地提醒其主人。",          "category" : "奇闻趣事",          "authors" : "",          "country" : "美国",          "timestamp" : 1693070640        }      },      .....    ]  }}

took字段和timed_out字段很容易理解,它们只代表Elasticsearch返回响应所花费的时间(以毫秒为单位),以及查询是否超时。

_shards字段告诉我们在此搜索操作中涉及了多少个分片,其中有多少个成功返回,有多少个失败,以及有多少个跳过。

hits字段包含从搜索中返回的文档。每个文档根据其与我们的搜索相关性的程度被赋予一个分数。hits字段还包含一个字段total,其中提到了返回的文档总数和文档的最高分数。

最后,在嵌套字段hits中,我们获取了所有相关的文档,以及它们的_idscore。文档按照它们的分数进行排序。

一个基本的搜索查询

让我们开始构建我们的搜索查询。我们可以从一个简单的查询开始,并逐步解析其中的问题。

GET news/_search{  "query": {    "multi_match": {      "query": "抢劫",      "fields": ["headline", "short_description"]    }  }}

这是一个非常简单的查询,它只找出所有在给定字段中出现词语“抢劫”的文档,即headlineshort_description

它返回了一些结果,我们可以看到所有这些结果中都包含词语“抢劫”。

{  .....  "hits" : {    "total" : {      "value" : 3,      "relation" : "eq"    },    "max_score" : 8.164355,    "hits" : [      {        "_index" : "news",        "_id" : "hjrouIsBC1dvdsZHgWdm",        "_score" : 8.164355,        "_source" : {          "link" : "https://www.huffpost.com/entry/lady-gaga-dog-walker-reward_n_62d82efee4b000da23fafad7",          "headline" : "获得5,000美元悬赏金,缉捕涉嫌射杀Lady Gaga的狗管家的犯罪嫌疑人",          "short_description" : "涉及这起暴力抢劫的两名男子中有一人在四月份误释放,目前下落不明。",          "category" : "美国新闻",          "authors" : "STEFANIE DAZIO, AP",          "country" : "印度",          "timestamp" : 1694863246        }      },      {        "_index" : "news",        "_id" : "RzrouIsBC1dvdsZHf2cP",        "_score" : 7.4066687,        "_source" : {          "link" : "https://www.huffpost.com/entry/guard-cat-hailed-as-hero_n_62e9a515e4b00f4cf2352a6f",          "headline" : "无止境抢劫",          "short_description" : "在上周,在密西西比州图佩洛的一所房子里有至少两个人试图闯入,这只猫竭尽所能地提醒其主人。",          "category" : "奇闻趣事",          "authors" : "",          "country" : "美国",          "timestamp" : 1693070640        }      },      {        "_index" : "news",        "_id" : "WTrouIsBC1dvdsZHp2wd",        "_score" : 7.4066687,        "_source" : {          "link" : "https://www.huffpost.com/entry/san-francisco-news-crew-security-guard-shot-killed_n_61a2a9d8e4b0ae9a42af278a",          "headline" : "新闻团队保安在帮助报道抢劫时被枪击身亡",          "short_description" : "由于有组织的零售犯罪的激增,Kevin Nishita在工作中被击中腹部。",          "category" : "犯罪",          "authors" : "Daisy Nguyen, AP",          "country" : "美国",          "timestamp" : 1692480894        }      }    ]  }}词汇搜索

到目前为止,我们所进行的都被称为“词汇搜索”。在这种类型的搜索中,系统会查找文档中给定词语或短语的精确匹配项。基本上,当用户输入“抢劫”时,我们的搜索查询会识别出所有包含确切词语“抢劫”的文档。尽管这种方法在开始时可能会看似直观,但它的限制很快就会显现出来,我们很快就会发现。

我们当前搜索查询中的问题

相似词语返回不同结果

我们来看几个例子,看看当用户搜索“被抢劫”时我们得到了什么结果 -

GET news/_search{  "query": {    "multi_match": {      "query": "被抢劫",      "fields": ["headline", "short_description"]    }  }}

以下是我得到的结果 -

{    "total" : {      "value" : 2,      "relation" : "eq"    },    "max_score" : 7.9044275,    "hits" : [      {        "_index" : "news",        "_id" : "YTrouIsBC1dvdsZHh2jf",        "_score" : 7.9044275,        "_source" : {          "link" : "https://www.huffpost.com/entry/multiple-guns-robbery-wellston-market-missouri_n_62994cbee4b05fe694f296ad",          "headline" : "男子在枪口下被抢劫,开第二把枪还击",          "short_description" : "被指控抢劫犯多次中弹,两名旁观者在圣路易斯的枪战中受伤。",          "category" : "犯罪",          "authors" : "Mary Papenfuss",          "country" : "IN",          "timestamp" : 1691458552        }      },      {        "_index" : "news",        "_id" : "YDrouIsBC1dvdsZH73UQ",        "_score" : 7.8303137,        "_source" : {          "link" : "https://www.huffpost.com/entry/michigan-militia-training-video-gretchen-whitmer_n_5f8b6e26c5b6dc2d17f78e0a",          "headline" : "发布军事训练视频,揭示密歇根州州长绑架阴谋",          "short_description" : "\"我厌倦了被国家抢劫和奴役...他们就是敌人。\" 一个嫌疑犯在一段视频中说。",          "category" : "政治",          "authors" : "Mary Papenfuss",          "country" : "IN",          "timestamp" : 1692613291        }      }    ]  }

为了简单起见,以下是我得到的文档标题

1. "男子在枪口下被抢劫,开第二把枪还击"2. "发布军事训练视频,揭示密歇根州州长绑架阴谋"

这两个文档中都包含了“被抢劫”这个词语,无论是在标题还是描述中。但是,如果用户搜索的是“抢劫”,那么我们会在结果中看到完全不同的一组文档 -

[      {        "_index" : "news",        "_id" : "hjrouIsBC1dvdsZHgWdm",        "_score" : 8.164355,        "_source" : {          "link" : "https://www.huffpost.com/entry/lady-gaga-dog-walker-reward_n_62d82efee4b000da23fafad7",          "headline" : "抢劫者枪杀Lady Gaga的狗遛狗师获5000美元赏金",          "short_description" : "在这次暴力抢劫中涉及的一名男子在四月份被错误释放,并至今下落不明。",          "category" : "美国新闻",          "authors" : "STEFANIE DAZIO, AP",          "country" : "IN",          "timestamp" : 1694863246        }      },      {        "_index" : "news",        "_id" : "YTrouIsBC1dvdsZHh2jf",        "_score" : 8.079888,        "_source" : {          "link" : "https://www.huffpost.com/entry/multiple-guns-robbery-wellston-market-missouri_n_62994cbee4b05fe694f296ad",          "headline" : "男子在枪口下被抢劫,开第二把枪还击",          "short_description" : "被指控抢劫犯多次中弹,两名旁观者在圣路易斯的枪战中受伤。",          "category" : "犯罪",          "authors" : "Mary Papenfuss",          "country" : "IN",          "timestamp" : 1691458552        }      },      {        "_index" : "news",        "_id" : "RzrouIsBC1dvdsZHf2cP",        "_score" : 7.4066687,        "_source" : {          "link" : "https://www.huffpost.com/entry/guard-cat-hailed-as-hero_n_62e9a515e4b00f4cf2352a6f",          "headline" : "被赞为英雄的“防贼猫”阻止即将发生的抢劫",          "short_description" : "上周,在密西西比州图佩洛的一所住宅中,至少有两名人试图闯入,这只猫尽其所能地提醒主人。",          "category" : "奇闻",          "authors" : "",          "country" : "US",          "timestamp" : 1693070640        }      },      {        "_index" : "news",        "_id" : "WTrouIsBC1dvdsZHp2wd",        "_score" : 7.4066687,        "_source" : {          "link" : "https://www.huffpost.com/entry/san-francisco-news-crew-security-guard-shot-killed_n_61a2a9d8e4b0ae9a42af278a",          "headline" : "新闻团队安保人员在帮助报道抢劫事件时被枪击身亡",          "short_description" : "在有组织的零售犯罪数量激增的情况下,Kevin Nishita在履行职责时被腹部中枪。",          "category" : "犯罪",          "authors" : "Daisy Nguyen, AP",          "country" : "US",          "timestamp" : 1692480894        }      }    ]

以下是结果中文档的标题:

1. "抢劫者枪杀Lady Gaga的狗遛狗师获5000美元赏金"2. "男子在枪口下被抢劫,开第二把枪还击"3. "被赞为英雄的“防贼猫”阻止即将发生的抢劫"4. "新闻团队安保人员在帮助报道抢劫事件时被枪击身亡"

总之,如果用户搜索“抢劫”,与用户搜索“被抢劫”时我们得到的结果是不同的。显然,这并不理想,如果用户搜索了这些词(或与“抢劫”相关的任何词),我们应该显示包含不同形式的词“抢劫”(称为“屈折”形式)的所有文档。

缺乏对用户需求的理解

“设计师的目标是倾听、观察、理解、同情、共感、综合,并从中获得洞察力,使他们能够使看不见的东西可见。”— Hillman Curtis

我们试图检索与用户查询相符的文档,这项任务超出了用户输入本身。通过深入研究附加参数,我们可以更加深入地了解用户的喜好和需求。

例如,当用户搜索新闻时,他们的兴趣往往超出了相关性本身,新闻文章的最新性通常至关重要。为了提高搜索精度,我们可以对评分机制进行微调。

此外,我们的文章还有一个 location 字段。该字段表示新闻的地理来源,为我们进一步优化结果提供了机会。我们可以使用它来提升来自用户所在国家的文章。

类似词没有返回

由于我们只返回包含用户查询的确切匹配的文章,我们可能会错过包含类似词的相关文档。例如,如果我搜索“盗窃”,我会得到以下文章:

[      {        "_index" : "news",        "_id" : "dzrouIsBC1dvdsZHiGh1",        "_score" : 8.079888,        "_source" : {          "link" : "https://www.huffpost.com/entry/ap-us-church-theft-beheaded-statue_n_629504abe4b0933e7376f2fa",          "headline" : "教堂天使雕像被斩首,价值200万美元的圣物被盗",          "short_description" : "这座纽约教堂表示其价值200万美元的18克拉黄金圣物曾受到自家安保系统的保护,由于历史和艺术价值而无法取代。",          "category" : "犯罪",          "authors" : "Michael R. Sisak,美联社",          "country" : "IN",          "timestamp" : 1699477455        }      },      {        "_index" : "news",        "_id" : "ATrouIsBC1dvdsZHrG2n",        "_score" : 7.4066687,        "_source" : {          "link" : "https://www.huffpost.com/entry/joseph-sobolewski-charge-dropped-mountain-dew-felony_n_617a15e0e4b0657357447ee2",          "headline" : "检察官撤销对以43美分购买山露被控犯罪的男子的指控",          "short_description" : "约瑟夫·索博列夫斯基支付2美元购买一瓶山露,价格为2.29美元加税,他面临最高7年监禁。",          "category" : "美国新闻",          "authors" : "尼克·维瑟",          "country" : "IN",          "timestamp" : 1698883200        }      },      {        "_index" : "news",        "_id" : "ZDrouIsBC1dvdsZH73Uq",        "_score" : 7.153779,        "_source" : {          "link" : "https://www.huffpost.com/entry/missing-lemur-found_n_5f8b2c33c5b6dc2d17f76bdb",          "headline" : "“这儿有只狐猴!”五岁孩子帮助破解旧金山动物园窃案",          "short_description" : "这只患有关节炎的21岁狐猴“激动不安”,但动物园工作人员表示它很安全。",          "category" : "美国新闻",          "authors" : "",          "country" : "IN",          "timestamp" : 1698560597        }      }    ]

“抢劫”这个词可能与“盗窃”这个词有不同的含义,但它仍然是一个相关的词,用户可能有兴趣看到含有“抢劫”这个词的文章(尽管与用户搜索的确切词相比,其相关性得分较低)

偷窃可能有很多类似的词,每个词的相似度级别不同。例如,“theft”可能与“shoplifting”更相似,而与“burglary”不太相似。但在某些情境下,它们可以相互等同,并且与查询中的确切词汇(即“theft”)有一定相关性。

我们目前的搜索不考虑文档和查询中单词的相似性。如果用户搜索“theft”,只返回包含词汇“theft”的文章,而我们应该还返回包含与“theft”相似的词汇(如“burglary”或“robbery”)的文章。

忽略错别字

“如果用户使用不了它,那它就没用。” —— Susan Dray

另一个问题是用户的任何拼写错误都会返回空结果。我们知道用户可能会不小心犯拼写错误,而我们不希望返回空结果。例如,在Google新闻上搜索“robbey”仍会返回与“robbery”相关的结果。

掌握Elasticsearch:强大搜索和精确性的入门指南-第1部分 四海 第2张

不同词组具有不同的含义

让我们看一个例子,假设用户进行了以下查询:

GET news/_search{  "query": {    "multi_match": {      "query": "new jersey covid virus"    }  }}

对于你和我来说,用户想要搜索与“covid”或“virus”有关的“新泽西州”的新闻是很明显的。但对于我们的搜索引擎来说,这些词的意思都是一样的,并且它无法理解这些词的排序关系(例如,“New Jersey”中的“New”和“Jersey”)。

让我们看看前三个结果:

{        "_index" : "news",        "_id" : "0jrouIsBC1dvdsZH03FH",        "_score" : 15.199991,        "_source" : {          "link" : "https://www.huffpost.com/entry/covid-new-york-new-jersey-trend_n_60611769c5b6531eed0621da",          "headline" : "病毒在早期热点纽约和新泽西的抗击受阻",          "short_description" : "在过去的14天里,新泽西每10万居民报告了约647起新病例。纽约的平均数量为548起。",          "category" : "美国新闻",          "authors" : "Marina Villeneuve和Mike Catalini, AP",          "country" : "美国",          "timestamp" : 1697056489        }      },      {        "_index" : "news",        "_id" : "zzrouIsBC1dvdsZH23Ig",        "_score" : 12.708103,        "_source" : {          "link" : "https://www.huffpost.com/entry/new-variants-raise-worry-about-covid-19-virus-reinfections_n_602193e6c5b689330e31dcc4",          "headline" : "新变种引发对COVID-19病毒再感染的担忧",          "short_description" : "科学家在南非发现了一种更具传染性且对某些治疗方法不太敏感的新病毒变种。",          "category" : "国际新闻",          "authors" : "Marilynn Marchione, AP`",          "country" : "印度",          "timestamp" : 1693063095        }      },      {        "_index" : "news",        "_id" : "fTrouIsBC1dvdsZH6HQF",        "_score" : 11.707885,        "_source" : {          "link" : "https://www.huffpost.com/entry/new-york-covid-19-religious-gatherings_n_5fbf42b8c5b66bb88c6430ac",          "headline" : "最高法院阻止对宗教集会实施的纽约COVID-19限制措施",          "short_description" : "这是自艾米·科尼·巴雷特(Amy Coney Barrett)法官加入美国最高法院以来的第一个重要决定。",          "category" : "政治",          "authors" : "Lawrence Hurley, Reuters",          "country" : "印度",          "timestamp" : 1693362371        }      },

如果你仔细看上面的结果,你会注意到第二个结果,“新变种引发对COVID-19病毒再感染的担忧”,与新泽西州完全无关。实际上,阅读描述后,它似乎更与南非的COVID-19感染有关!

这是因为“COVID”,“病毒”和“新”这些词是文档的一部分,因此文档得分更高。然而,这与用户的查询毫不相关。我们的搜索系统不能理解“新”和“泽西州”这些词应该作为一个单词处理。

提升更相关的字段

“词语有重量,所以如果你要说重要的事情,确保选择正确的词语。”—— Lang Leav

我们可以决定提升某些字段或某些值,这些字段或值在了解文章内容方面可能更有用。例如,文章的标题可能比文章的描述更有意义。

让我们来看一个示例查询。假设用户想搜索选举,这将是我们的Elasticsearch查询-

GET news/_search{  "query": {    "multi_match": {      "query": "elections",      "type": "most_fields",       "fields": ["short_description", "headline"]    }  }}

我们得到的结果如下-

{        "_index" : "news",        "_id" : "qDrouIsBC1dvdsZHwW-a",        "_score" : 15.736175,        "_source" : {          "link" : "https://www.huffpost.com/entry/new-york-city-board-of-elections-mess_n_60de223ee4b094dd26898361",          "headline" : "为什么纽约市选举委员会一团糟",          "short_description" : "“拥有党派选举委员会存在根本性问题,”纽约选举律师说。",          "category" : "政治",          "authors" : "Daniel Marans",          "country" : "印度",          "timestamp" : 1689878099        }      },      {        "_index" : "news",        "_id" : "8zrouIsBC1dvdsZH63Si",        "_score" : 7.729385,        "_source" : {          "link" : "https://www.huffpost.com/entry/20-funniest-tweets-from-women-oct-31-nov-6_n_5fa209fac5b686950033b3e7",          "headline" : "本周女性发出的20条最有趣的推文(10月31日至11月6日)",          "short_description" : "“听我说:对于选举来说,应该有硬性规定。”",          "category" : "女性",          "authors" : "Caroline Bologna",          "country" : "印度",          "timestamp" : 1694723723        }      },      {        "_index" : "news",        "_id" : "zzrouIsBC1dvdsZH8nVe",        "_score" : 7.353842,        "_source" : {          "link" : "https://www.huffpost.com/entry/childrens-books-elections-voting_l_5f728844c5b6f622a0c368a1",          "headline" : "25本教孩子了解选举和投票的儿童书籍",          "short_description" : "父母可以利用这些故事来教育孩子了解美国的政治进程。",          "category" : "育儿",          "authors" : "Caroline Bologna",          "country" : "印度",          "timestamp" : 1697290393        }      },

如果你看一下第二篇文章“本周女性发出的20条最有趣的推文(10月31日至11月6日)”,你会发现它似乎与选举无关。然而,由于描述中存在“选举”一词,Elasticsearch认为它是一个相关的结果。也许,还有改进的空间。直觉上,标题与用户的查询匹配的文章会更相关。为了实现这一点,我们可以指示Elasticsearch提升heading字段,从而在得分计算中赋予它比short_description字段更重要的重要性。

这在我们的查询中非常简单-

GET news/_search{  "query": {    "multi_match": {      "query": "选举",      "type": "most_fields",       "fields": ["headline^4", "short_description"]    }  }}

注意我在 fields 中加入的 heading^4。这意味着字段“heading”会受到4倍的加权。现在让我们来看一下结果,

{        "_index" : "news",        "_id" : "qDrouIsBC1dvdsZHwW-a",        "_score" : 37.7977,        "_source" : {          "link" : "https://www.huffpost.com/entry/new-york-city-board-of-elections-mess_n_60de223ee4b094dd26898361",          "headline" : "为何纽约市选举局一团糟",          "short_description" : "“党派选举委员会存在根本问题,”纽约选举律师表示。",          "category" : "政治",          "authors" : "Daniel Marans",          "country" : "IN",          "timestamp" : 1689878099        }      },      {        "_index" : "news",        "_id" : "zzrouIsBC1dvdsZH8nVe",        "_score" : 29.415367,        "_source" : {          "link" : "https://www.huffpost.com/entry/childrens-books-elections-voting_l_5f728844c5b6f622a0c368a1",          "headline" : "25本教孩子们选举和投票的儿童书籍",          "short_description" : "家长可以使用这些故事来教育孩子美国政治流程。",          "category" : "育儿",          "authors" : "Caroline Bologna",          "country" : "IN",          "timestamp" : 1697290393        }      },      {        "_index" : "news",        "_id" : "_jrouIsBC1dvdsZH3HKZ",        "_score" : 29.415367,        "_source" : {          "link" : "https://www.huffpost.com/entry/shirley-weber-first-black-california-secretary-of-state_n_6014651ec5b6aa4bad33e87b",          "headline" : "Shirley Weber宣誓就职为加州首位黑人选举主管",          "short_description" : "她放弃了自己的议会席位成为新一任国务卿,接替上周当选为加州首位拉美裔美国参议员的亚历克斯·帕迪利亚。",          "category" : "政治",          "authors" : "Sarah Ruiz-Grossman",          "country" : "IN",          "timestamp" : 1697300728        }      },      {        "_index" : "news",        "_id" : "NzrouIsBC1dvdsZHnWvd",        "_score" : 26.402336,        "_source" : {          "link" : "https://www.huffpost.com/entry/josh-hawley-democrats-dont-accept-elections_n_61ea1949e4b01440a689bedc",          "headline" : "参议员Josh Hawley无畏地表示,民主党不接受输掉的选举",          "short_description" : "这位密苏里共和党人在1月6日领头反对乔·拜登的胜利,紧接着向在美国国会大厦集会的亲特朗普抗议者致意。",          "category" : "政治",          "authors" : "Josephine Harvey",          "country" : "IN",          "timestamp" : 1692046727        }      },

现在我们可以看到所有排名靠前的结果中都包含“选举”一词,因此返回的文章更相关。

基于函数的加权

虽然我们对某些字段进行了加权,但我们还想根据用户在搜索新闻时的需求引入两种新类型的加权。

  1. 我们想要加权用户所在国家的文章。我们不仅仅想根据国家进行筛选,因为那可能会导致出现不相关的结果排在前面,但我们也不想完全忽略国家。简而言之,我们希望给用户所在国家的文章更多的权重。
  2. 我们想要加权较新的新闻。我们不仅仅想根据新闻的新旧程度进行排序,因为那也可能导致不相关的结果排在前面,相反,我们希望在新旧程度和相关性之间取得平衡。

让我们看看如何完成这个任务。

在Elasticsearch中,我们可以使用function_score查询来应用自定义评分函数,包括boosting。 function_score查询允许你根据不同的函数修改文档的分数。简单来说,我们可以根据条件提升某些文档的分数。

让我们首先提升用户的国家。假设用户的国家是“US”,在将查询发送到Elasticsearch时将其插入到查询中。为了实现这一点,我们需要添加一个function_score块,它允许对查询结果应用自定义评分函数。我们可以为给定的查询定义多个functions,指定匹配文档和提升值的条件。

我们可以定义一个函数来提升用户的国家 —

{  "filter": {    "term": {      "country.keyword": "US"    }  },  "weight": 2}

这会在国家为“US”的文章上提升2倍。

接下来,让我们尝试将最新的新闻放在前面。我们可以使用field_value_factor来实现这一点。 field_value_factor函数允许我们使用文档中的字段来影响其分数,这正是我们想要的。让我们看看它是怎样的 —

{  "field_value_factor": {    "field": "timestamp",    "factor": 2  }}

术语factor指定了指定字段的值应该如何影响分数的乘数或因子。通过使用这个函数,具有更新时间戳的文档将获得更高的分数。

我们的完整查询如下 —

GET news/_search{  "query": {    "bool": {      "must": [        {          "multi_match": {            "query": "covid",            "fields": ["headline^4", "short_description"]          }        },        {          "function_score": {            "query": {              "multi_match": {                "query": "covid",                "fields": ["headline^4", "short_description"]              }            },            "functions": [              {                "filter": {                  "term": {                    "country.keyword": "US"                  }                },                "weight": 2              }, {                "field_value_factor": {                  "field": "timestamp",                  "factor": 2                }              }            ]          }        }      ]    }  }}

现在最新的文档和用户所在国家的文档将获得更高的分数。通过配置weightfactor字段的值,我们可以调整这种平衡。

模糊查询

接下来,让我们纠正搜索查询中的拼写错误。

在Elasticsearch中,我们可以进行模糊搜索,以检索与指定术语匹配的文档,即使在拼写或字符上稍有变化也可以。为了实现这一点,我们只需在查询中添加一个fuzziness字段。我们最终的查询如下 —

GET news/_search{  "query": {    "bool": {      "must": [        {          "multi_match": {            "query": "covi",            "fields": ["headline^4", "short_description"],            "fuzziness": 1          }        },        {          "function_score": {            "query": {              "multi_match": {                "query": "covi",                "fields": ["headline^4", "short_description"],                "fuzziness": 1              }            },            "functions": [              {                "filter": {                  "term": {                    "country.keyword": "US"                  }                },                "weight": 2              }, {                "field_value_factor": {                  "field": "timestamp",                  "factor": 2                }              }            ]          }        }      ]    }  }}

拼写纠正并不仅仅是添加fuzziness。如果想要了解更多信息,请查阅这篇博客文章。

结论

在这篇博客文章中,我们深入研究了Elasticsearch的核心技术,从实际数据集和构建搜索查询的基础知识入手。我们解析了Elasticsearch的响应,并介绍了基本的搜索查询,为有效的探索奠定了基础。

在我们探索词汇搜索时,我们注意到了我们当前搜索方法中的一些怪异之处。为了解决这些挑战,我们引入了增强和模糊度-这些工具可以微调我们的搜索,处理真实世界的数据复杂性。

在这里结束之际,将这视为我们追求卓越搜索旅程中的一个停留点。在下一部分中,我们将深入研究先进的策略,以克服当前搜索方法中的特定问题。为自己做好准备,进入语义搜索的奇妙世界,其中重点从仅仅匹配关键词转向理解其背后的意义,为更具直观性和上下文感知的搜索体验铺平道路。准备好将您的Elasticsearch冒险推向更高境界吧!

喜欢通过Elasticsearch的旅程吗?在VoAGI上关注我,以获取更多文章。想要更快地获取知识点(关于我正在阅读的内容的小贴士、备忘录等),在LinkedIn上关注我,我会定期发布简短的内容(例如,当我了解Elasticsearch时,我在这里简单介绍了一个称为tf-idf的特定评分函数是如何工作的,在5分钟的帖子中进行了讨论)。让我们在这个科技和数据的探索中保持联系吧!

Leave a Reply

Your email address will not be published. Required fields are marked *