基于 Serverless 快速实现简单版查询工具

本文涉及的产品
Serverless 应用引擎免费试用套餐包,4320000 CU,有效期3个月
函数计算FC,每月15万CU 3个月
简介: 朋友的单位有一个小型的图书室,图书室中摆放了很多的书,每本书都被编号放在对应的区域,为了让大家更快、更容易找到这些书,他联系我,让我帮他弄一个图书查询系统,通过用户输入能模糊匹配到对应的结果,并且提供书籍对应的地点。

云栖号资讯:【点击查看更多行业资讯
在这里您可以找到不同行业的第一手的上云资讯,还在等什么,快来!

朋友的单位有一个小型的图书室,图书室中摆放了很多的书,每本书都被编号放在对应的区域,为了让大家更快、更容易找到这些书,他联系我,让我帮他弄一个图书查询系统,通过用户输入能模糊匹配到对应的结果,并且提供书籍对应的地点。

功能设计

  • 让朋友把书籍整理并存储到一个 Excel 表格中;
  • 将 Excel 表放到对象存储中,云函数读取这个文件并解析;
  • 根据词语的相似寻找相似的图书;
  • 前端页面通过 MUI 制作,放在对象存储中,并且使用对象存储的 Website 功能;

整体实现

数据形态
Excel 样式主要包括书名和编号,同时下面包括分类的 tab:

761AB451_6478_4f2c_80DA_57A31B44195C

基于函数的搜索功能

核心代码实现:

import jieba
import openpyxl
from gensim import corpora, models, similarities
from collections import defaultdict
import urllib.request

with open("/tmp/book.xlsx", "wb") as f:
    f.write(
        urllib.request.urlopen("https://********").read()
    )


top_str = "abcdefghijklmn"
book_dict = {}
book_list = []
wb = openpyxl.load_workbook('/tmp/book.xlsx')
sheets = wb.sheetnames
for eve_sheet in sheets:
    print(eve_sheet)
    sheet = wb.get_sheet_by_name(eve_sheet)
    this_book_name_index = None
    this_book_number_index = None
    for eve_header in top_str:
        if sheet[eve_header][0].value == " 书名 ":
            this_book_name_index = eve_header
        if sheet[eve_header][0].value == " 编号 ":
            this_book_number_index = eve_header
    print(this_book_name_index, this_book_number_index)
    if this_book_name_index and this_book_number_index:
        this_book_list_len = len(sheet[this_book_name_index])
        for i in range(1, this_book_list_len):
            add_key = "%s_%s_%s" % (
                sheet[this_book_name_index][i].value, eve_sheet, sheet[this_book_number_index][i].value)
            add_value = {
                "category": eve_sheet,
                "name": sheet[this_book_name_index][i].value,
                "number": sheet[this_book_number_index][i].value
            }
            book_dict[add_key] = add_value
            book_list.append(add_key)


def getBookList(book, book_list):
    documents = []
    for eve_sentence in book_list:
        tempData = " ".join(jieba.cut(eve_sentence))
        documents.append(tempData)
    texts = [[word for word in document.split()] for document in documents]
    frequency = defaultdict(int)
    for text in texts:
        for word in text:
            frequency[word] += 1
    dictionary = corpora.Dictionary(texts)
    new_xs = dictionary.doc2bow(jieba.cut(book))
    corpus = [dictionary.doc2bow(text) for text in texts]
    tfidf = models.TfidfModel(corpus)
    featurenum = len(dictionary.token2id.keys())
    sim = similarities.SparseMatrixSimilarity(
        tfidf[corpus],
        num_features=featurenum
    )[tfidf[new_xs]]
    book_result_list = [(sim[i], book_list[i]) for i in range(0, len(book_list))]
    book_result_list.sort(key=lambda x: x[0], reverse=True)
    result = []
    for eve in book_result_list:
        if eve[0] >= 0.25:
            result.append(eve)
    return result


def main_handler(event, context):
    try:
        print(event)
        name = event["body"]
        print(name)
        base_html = '''<div class='mui-card'><div class='mui-card-header'>{{book_name}}</div><div class='mui-card-content'><div class='mui-card-content-inner'> 分类:{{book_category}}<br> 编号:{{book_number}}</div></div></div>'''
        result_str = ""
        for eve_book in getBookList(name, book_list):
            book_infor = book_dict[eve_book[1]]
            result_str = result_str + base_html.replace("{{book_name}}", book_infor['name']) \
                .replace("{{book_category}}", book_infor['category']) \
                .replace("{{book_number}}", book_infor['number'] if book_infor['number'] else "")
        if result_str:
            return result_str
    except Exception as e:
        print(e)
    return '''<div class='mui-card' style='margin-top: 25px'><div class='mui-card-content'><div class='mui-card-content-inner'> 未找到图书信息,请您重新搜索。</div></div></div>'''

同时配置 APIGW:

660F700C_BEB7_4d2d_94E2_FB4C9E42D18B

功能页面

<!DOCTYPE html>
<html>
<head>
   <meta charset="utf-8">
   <title>图书检索系统</title>
   <meta name="viewport" content="width=device-width, initial-scale=1,maximum-scale=1,user-scalable=no">
   <meta name="apple-mobile-web-app-capable" content="yes">
   <meta name="apple-mobile-web-app-status-bar-style" content="black">

   <link rel="stylesheet" href="https://others-1256773370.cos.ap-chengdu.myqcloud.com/booksearch/css/mui.min.css">
   <style>
       html,
       body {
           background-color: #efeff4;
       }
</style>
   <script>
       function getResult() {
           var UTFTranslate = {
               Change: function (pValue) {
                   return pValue.replace(/[^\u0000-\u00FF]/g, function ($0) {
                       return escape($0).replace(/(%u)(\w{4})/gi, "&#x$2;")
                   });
               },
               ReChange: function (pValue) {
                   return unescape(pValue.replace(/&#x/g, '%u').replace(/\\u/g, '%u').replace(/;/g, ''));
               }
           };

           var xmlhttp;
           if (window.XMLHttpRequest) {
               // IE7+, Firefox, Chrome, Opera, Safari 浏览器执行代码
               xmlhttp = new XMLHttpRequest();
           } else {
               // IE6, IE5 浏览器执行代码
               xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
           }
           xmlhttp.onreadystatechange = function () {
               if (xmlhttp.readyState == 4 && xmlhttp.status == 200 && xmlhttp.responseText) {
                   document.getElementById("result").innerHTML = UTFTranslate.ReChange(xmlhttp.responseText).slice(1, -1).replace("\"",'"');
               }
           }
           xmlhttp.open("POST", "https://********", true);
           xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
           xmlhttp.send(document.getElementById("book").value);
       }
</script>
</head>
<body>
<div class="mui-content" style="margin-top: 50px">
   <h3 style="text-align: center">图书检索系统</h3>
   <div class="mui-content-padded" style="margin: 10px; margin-top: 20px">
       <div class="mui-input-row mui-search">
           <input type="search" class="mui-input-clear" placeholder="请输入图书名" id="book">
       </div>
       <div class="mui-button-row">
           <button type="button" class="mui-btn mui-btn-numbox-plus" style="width: 100%" onclick="getResult()">检索
           </button>&nbsp;&nbsp;
       </div>
   </div>
   <div id="result">
       <div class="mui-card" style="margin-top: 25px">
           <div class="mui-card-content">
               <div class="mui-card-content-inner">
                   可以在搜索框内输入书籍的全称,或者书籍的简称,系统支持智能检索功能。
               </div>
           </div>
       </div>
   </div>
</div>
<script src="https://others-1256773370.cos.ap-chengdu.myqcloud.com/booksearch/js/mui.min.js"></script>
</body>
</html>

效果展示

为了便于朋友使用,我将这个页面用 Webview 封装成一个 APP,整体效果如下:

62AA37C8_77AB_4b08_970A_B73D10485329

总结

这是一个低频使用的 APP,如果是构建在传统服务器上,不是一个明智的选择,而云函数的按量付费,对象存储与 APIGW 的融合,完美解决了资源浪费的问题,同时借用云函数的 APIGW 触发器,可以很简单轻松的替代传统的 Web 框架和部分服务器软件的安装和使用、维护等。这个例子非常小,但却是一个有趣的小工具,除了图书查询之外,我们还可以继续拓展构建其它系统,例如成绩查询等。

【云栖号在线课堂】每天都有产品技术专家分享!
课程地址:https://yqh.aliyun.com/zhibo

立即加入社群,与专家面对面,及时了解课程最新动态!
【云栖号在线课堂 社群】https://c.tb.cn/F3.Z8gvnK

原文发布时间:2020-06-28
本文作者: 刘宇
本文来自:“InfoQ ”,了解相关信息可以关注“[InfoQ](https://mp.weixin.qq.com/s/6z7ByuwbgqGlP15nRtvkLA

相关实践学习
【文生图】一键部署Stable Diffusion基于函数计算
本实验教你如何在函数计算FC上从零开始部署Stable Diffusion来进行AI绘画创作,开启AIGC盲盒。函数计算提供一定的免费额度供用户使用。本实验答疑钉钉群:29290019867
建立 Serverless 思维
本课程包括: Serverless 应用引擎的概念, 为开发者带来的实际价值, 以及让您了解常见的 Serverless 架构模式
相关文章
|
弹性计算 监控 安全
函数计算进阶-IP查询工具开发
本场景介绍如何使用函数计算服务开发一个IP查询工具。
|
3月前
|
运维 监控 Serverless
函数计算产品使用问题之怎么查询在特定时间段内应用的调用次数
函数计算产品作为一种事件驱动的全托管计算服务,让用户能够专注于业务逻辑的编写,而无需关心底层服务器的管理与运维。你可以有效地利用函数计算产品来支撑各类应用场景,从简单的数据处理到复杂的业务逻辑,实现快速、高效、低成本的云上部署与运维。以下是一些关于使用函数计算产品的合集和要点,帮助你更好地理解和应用这一服务。
|
4月前
|
运维 监控 JavaScript
函数计算产品使用问题之如何查询文生图接口地址
函数计算产品作为一种事件驱动的全托管计算服务,让用户能够专注于业务逻辑的编写,而无需关心底层服务器的管理与运维。你可以有效地利用函数计算产品来支撑各类应用场景,从简单的数据处理到复杂的业务逻辑,实现快速、高效、低成本的云上部署与运维。以下是一些关于使用函数计算产品的合集和要点,帮助你更好地理解和应用这一服务。
|
4月前
|
负载均衡 Java Serverless
函数计算产品使用问题之如何查看函数计算的QPS(每秒查询率)
函数计算产品作为一种事件驱动的全托管计算服务,让用户能够专注于业务逻辑的编写,而无需关心底层服务器的管理与运维。你可以有效地利用函数计算产品来支撑各类应用场景,从简单的数据处理到复杂的业务逻辑,实现快速、高效、低成本的云上部署与运维。以下是一些关于使用函数计算产品的合集和要点,帮助你更好地理解和应用这一服务。
|
5月前
|
运维 Java Serverless
Serverless 应用引擎产品使用合集之是否提供工具来给OSS配置HTTPS证书
阿里云Serverless 应用引擎(SAE)提供了完整的微服务应用生命周期管理能力,包括应用部署、服务治理、开发运维、资源管理等功能,并通过扩展功能支持多环境管理、API Gateway、事件驱动等高级应用场景,帮助企业快速构建、部署、运维和扩展微服务架构,实现Serverless化的应用部署与运维模式。以下是对SAE产品使用合集的概述,包括应用管理、服务治理、开发运维、资源管理等方面。
|
6月前
|
运维 数据挖掘 Serverless
阿里云Elasticsearch Serverless助力某电商平台公司实现商品订单数据的实时写入查询
某电商平台公司采用阿里云Elasticsearch Serverless解决方案,实现商品、订单和其他关键信息的写入和查询的实时响应。
420 1
|
6月前
|
Kubernetes 前端开发 Serverless
Serverless 应用引擎报错问题之部署报错如何解决
Serverless部署是指将应用程序部署到无服务器架构中,该架构允许开发者专注于代码而无需关心底层服务器的运行和维护;针对Serverless部署过程中可能遇到的挑战,本合集提供全面的指南和最佳实践,帮助开发者顺利实现应用的无服务器化部署。
190 1
|
6月前
|
监控 Serverless API
Serverless Devs是一个开源的Serverless应用全生命周期管理工具
Serverless Devs是一个开源的Serverless应用全生命周期管理工具
200 1
|
Devops Serverless 持续交付
函数计算持续交付入门:云效+FC实现 简单IP查询工具
本场景介绍如何使用云效自动发布应用到函数计算平台。
|
Serverless 开发工具 数据库
Serverless 移动研发平台EMAS云函数管理工具
Aliyun EMAS Serverless 移动研发平台EMAS云函数管理
132 0

热门文章

最新文章

相关产品

  • 函数计算