开发者社区> 豪三> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

使用Elasticsearch快速搭建食谱搜索系统

简介: 搜索是一个网站的基础功能,一个好的搜索系统可以直接促进页面访问量的提升,目前流行的搜索系统方案都是基于开源的Elasticsearch和Solr搭建。本文以食谱搜索场景为例,介绍如何利用阿里云Elasticsearch快速搭建一个搜索系统。
+关注继续查看

搜索是一个网站的基础功能,一个好的搜索系统可以直接促进页面访问量的提升,目前流行的搜索系统方案都是基于开源的Elasticsearch和Solr搭建。本文以食谱搜索场景为例,介绍如何利用阿里云Elasticsearch快速搭建一个搜索系统。

阅读本文,需要先理解了Elasticsearch相关概念,如索引、类型、文档、映射等。

开通阿里云Elasticsearch服务

由于阿里云Elasticsearch目前支持的网络类型只有用户自有的专有网络(VPC),所以在开通Elasticsearch服务时,如果没有实现创建好的专有网络可选择,则会默认创建一个专有网络。

开通好Elasticsearch服务之后,可能会遇到一个新的问题,即业务系统部署在经典网络的ECS中,默认是无法访问专有网络的,所以需要通过专有网络中提供的Classiclink 的功能,打通经典网络访问专有网络的链路

完成上述步骤后,可以在业务系统所在的ECS上使用curl命令进行测试,也可以在阿里云Elasticsearch集成的Kibana控制台Dev Tools界面进行测试。

食谱搜索系统设计

5f3c0824adc23cfadf7f603a3fda1a93c6c3a2d8

如上图所示,爬虫从网上抓取食谱数据,先经过关键词提取和加工,得到搜索源数据,然后通过索引构建器调用Elasticsearch提供的Rest API完成索引的创建。同时,提取出食材名称和食谱标签静态数据,用于后续搜索过程中,调Elasticsearch服务前的业务判断。

数据准备及搜索场景设计

如下是一个典型的经过爬虫抓取、加工处理后用于搜索的食谱数据,索引构建器基于该数据结构创建索引和文档。

 {
    "recipeName": "水煮牛肉 ",                            //食谱名称
    "mainFood": "莴笋尖,瘦牛肉",                          //主料
    "subFood": "花椒面,菜籽油,豆瓣酱,蒜,鸡精",             //配料
    "recipeTag": "肉类,川菜,朋友聚餐",                    //食谱标签
    "viewNum": "3155800",                               //浏览次数
    "cookingSpareTime": "10-30分钟"                     //烹饪耗时
}

设计的搜索场景如下:

  • 场景1,根据食谱名称精确匹配
    输入 水煮牛肉

输出 水煮牛肉食谱

  • 场景2,根据单个食材名称模糊匹配主料和配料,得到包含该食材的食谱列表
    输入 牛肉

输出 相关食谱列表

  • 场景3,根据多个名称组合,可能是食材名称/食谱名称/食谱标签,匹配相关食谱列表
    输入 牛肉 川菜

输出 相关食谱列表

  • 场景4,根据食谱标签匹配包含该标签的食谱列表
    输入 川菜

输出 包含“川菜”标签的食谱列表

  • 场景5,搜索出浏览次数TOP10的食谱

索引创建

阿里云Elasticsearch默认关闭了自动创建索引功能,需要先创建好索引。索引的分析器使用阿里云Elasticsearch服务预置的IK Analyzer插件,该插件也是开源社区热门的中文分词分析器,结合食谱搜索的场景,使用ik_smart分析器对文本进行粗粒度的拆分。

根据搜索场景的需求,需要创建一个索引(Index),包含一个类型(Type),其中食谱名称(recipeName)、主要食材(mainFood)、辅助食材(subFood)、食谱标签(recipeTag)都是可被分词索引的,浏览次数(viewNum)可被索引但不进行分词,剩余不用于搜索的字段可不进行索引。

创建索引的命令如下:

curl -X PUT 'es-cn-xxx.elasticsearch.aliyuncs.com:9200/recipe' -d '
{
  "mappings": {
    "dish": {
      "properties": {
        "recipeName": {
          "type": "string",
          "index": "analyzed",
          "analyzer": "ik_smart"
        },
        "mainFood": {
          "type": "string",
          "index": "analyzed",
          "analyzer": "ik_smart"
        },
        "subFood": {
          "type": "string",
          "index": "analyzed",
          "analyzer": "ik_smart"
        },
        "recipeTag": {
          "type": "string",
          "index": "analyzed",
          "analyzer": "ik_smart"
        },
        "viewNum": {
          "type": "integer",
          "index": "not_analyzed"
        },
        "cookingSpareTime": {
          "type": "string",
          "index": "not_analyzed"
        }
      }
    }
  }
}'

索引文档创建

本文所设计的食谱搜索系统是一个实时的搜索系统,爬虫会不断的抓取数据,经过提取加工后由索引构建器调API创建文档,这样也能发挥ElasticSearch在实时搜索方面的优势。

如果有需要在ElasticSearch中大批量创建文档的需求,可以选择使用阿里云数据集成服务从OSS中抽取服务导入到ElasticSearch。

文档创建命令如下:

PUT 'es-cn-xxx.elasticsearch.aliyuncs.com:9200/recipe/dish/1' -d '
{
    "subFood": "花椒面,菜籽油,豆瓣酱,蒜,鸡精", 
    "collectNum": "189919", 
    "mainFood": "莴笋尖,瘦牛肉", 
    "recipeName": "水煮牛肉 ", 
    "viewNum": "3155800", 
    "recipeTag": "肉类,川菜,朋友聚餐",
    "cookingSpareTime": "10-30分钟"
}'  

搜索场景实现

场景1,根据食谱名称精确匹配    
场景2,根据单个食材名称模糊匹配主料和配料,得到包含该食材的食谱列表    
场景3,根据多个名称组合,可能是食材名称/食谱名称/食谱标签,匹配相关食谱列表
场景4,根据食谱标签匹配包含该标签的食谱列表

针对以上场景的需求,搜索后台的逻辑如下图所示:
cb689cf53e9d44bbca065e46b7c788da48437015

各个场景下的搜索过程对应Elasticsearch执行命令分别如下:

  • 场景1.
GET 'es-cn-xxx.elasticsearch.aliyuncs.com:9200/recipe/dish/_search' -d '
{
  "query" : { "term" : { "recipeName" : "水煮牛肉" }}
}'
  • 场景2.
GET 'es-cn-xxx.elasticsearch.aliyuncs.com:9200/recipe/dish/_search' -d '
{
  "query" : {
    "multi_match": { 
        "query":    "牛肉", 
        "fields":   [ "mainFood", "subFood" ] 
    }
  }
}'
  • 场景3.
GET 'es-cn-xxx.elasticsearch.aliyuncs.com:9200/recipe/dish/_search' -d '
{
  "query" : {
    "multi_match": { 
        "query":    "牛肉 川菜", 
        "fields":   [ "recipeName", "mainFood", "subFood", "recipeTag" ] 
    }
  }
}'
  • 场景4.
GET 'es-cn-xxx.elasticsearch.aliyuncs.com:9200/recipe/dish/_search' -d '
{
  "query" : { "match" : { "recipeTag" : "川菜" }}
}'
  • 场景5,搜索出流量次数TOP100的食谱
    该场景需要用到搜索排序,并指定搜索返回的记录数是100(默认为10)。
GET 'es-cn-xxx.elasticsearch.aliyuncs.com:9200/recipe/dish/_search' -d '
{
  "size": 100,
  "sort": { "viewNum": { "order": "desc" } }
}'

加入钉钉技术讨论群

dingQR

阿里云Elasticsearch已正式发布啦,Elastic开源官方联合开发,集成5.5商业版本XPack功能,欢迎开通使用。
点击了解更多产品信息

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
+关注
豪三
从贵州电信网厅,到阿尔巴尼亚TTNET、委内瑞拉Cantv的固网激活等项目,再到激活产品研发,在中兴软创国际OSS产品线开发岗位上有6年开发经验,如今在阿里云业务运营中台做商品和账务,对企业级应用开发和架构有丰富经验。
文章
问答
来源圈子
更多
相关文档: Elasticsearch
文章排行榜
最热
最新
相关电子书
更多
基于 Elasticsearch 电商搜索
立即下载
EYou—阿里云Elasticsearch智能优化运维工具分享
立即下载
阿里云Elasticsearch体系架构与特性解析
立即下载