I have a friend (this friend is not me). There is a small library in my friend's unit. There are many books in the library.
Although each book is numbered in the corresponding area, after all, there is no library management system, so it will take some time to find it. In order to make it easier for you to find these books, my friend contacted me and intended me to help him to make a simple book query system (< del > complete library management system < / del >).
Easier said that done, considering that this is still a complex project, I plan to use Tencent cloud function SCF to deploy the whole application to the Serverless architecture.
▎ overall effect
On the left is the homepage of the book retrieval system; on the right is the retrieval demonstration. For example, if we search "spirit", the App will return relevant books based on it. It doesn't look bad.
▎ functional design
- Store the Excel table containing book information in Tencent cloud object storage COS;
- Use Tencent cloud function to read and parse the table;
- Search corresponding books according to word similarity;
- The front page is made by MUI, and the page is also stored in COS.
▎ specific implementation
- Excel style (including title and number)
Classification tab:
- Core code implementation:
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 == "Title": this_book_name_index = eve_header if sheet[eve_header][0].value == "number": 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'>Classification:{{book_category}}<br>Serial number:{{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'>No book information found, please search again.</div></div></div>'''
- APIGW configuration:
- Home code:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Book retrieval system</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 browser execution code xmlhttp = new XMLHttpRequest(); } else { // IE6, IE5 browser execution code 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">Book retrieval system</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="Please enter the book name" id="book"> </div> <div class="mui-button-row"> <button type="button" class="mui-btn mui-btn-numbox-plus" style="width: 100%" onclick="getResult()">retrieval </button> </div> </div> <div id="result"> <div class="mui-card" style="margin-top: 25px"> <div class="mui-card-content"> <div class="mui-card-content-inner"> //You can enter the full name of the book or the short name of the book in the search box. The system supports the intelligent retrieval function. </div> </div> </div> </div> </div> <script src="https://others-1256773370.cos.ap-chengdu.myqcloud.com/booksearch/js/mui.min.js"></script> </body> </html>
- Finally, an App is encapsulated through Webview.
Summary
In fact, this is a low-frequency App. After all, there are not many books in the unit library, and the traffic is not large. If it is deployed on a traditional server, it may not be a good choice. After all, it costs money to put the server there regardless of whether it is used or not.
So here we choose the Serverless architecture and deploy it on the cloud function. The pay as you go feature can save a lot of costs. At the same time, through the combination of APIGW and COS, the problem of resource waste is solved perfectly. Tencent cloud Serverless Framework It is also a very useful developer tool. In addition, APIGW trigger of cloud function is also used here, which can easily replace the installation, use and maintenance of traditional Web framework and some server software.
This is just a small application, but with a little transformation, it can also be made into an App to query results. The application scenario of Serverless is very imaginative.
Portal:
- GitHub: github.com/serverless
- Official website: serverless.com
Welcome to: Serverless Chinese network , you can Best practices Experience more about Serverless application development!
Recommended reading: Serverless architecture: from principle, design to project implementation