neo4j构建算法_使用neo4j构建餐厅推荐引擎
neo4j构建算法
Building on top of our previous guide on Neo4j, we are going to make full use of our knowledge and build a restaurant recommender system today. Make sure that you have a working version of Neo4j. If you are new to Neo4j, it is highly recommended to go through the following guide on The Beginner’s Guide to the Neo4j Graph Platform before you continue. At the end of the day, you should have a working web application that returns the recommended restaurants based on your input.
在以前的Neo4j指南的基础上,我们将充分利用我们的知识,并在今天建立一个餐厅推荐系统。 确保您具有Neo4j的工作版本。 如果您不熟悉Neo4j,则强烈建议您先阅读Neo4j Graph平台初学者指南中的以下指南。 在一天结束时,您应该有一个可运行的Web应用程序,该应用程序根据您的输入返回推荐的餐厅。
1.设定 (1. Setup)
Neo4j (Neo4j)
I am using Neo4j community version 4.1.1 for this tutorial. Open up a terminal and change the directory to the root folder of Neo4j. Since the root folder resides in my C drive, my working directory is as follows:
我在本教程中使用Neo4j社区版本4.1.1。 打开终端,将目录更改为Neo4j的根文件夹。 由于根文件夹位于我的C驱动器中,因此我的工作目录如下:
C:\neo4j-community-4.1.1
Change the directory into the bin folder by running the following command:
通过运行以下命令将目录更改为bin文件夹:
cd bin
Now, you can start Neo4j either as a console application or background service. For a console application, run the following command:
现在,您可以将Neo4j作为控制台应用程序或后台服务启动。 对于控制台应用程序,运行以下命令:
neo4j console
Use the following command for starting it as a background service:
使用以下命令将其作为后台服务启动:
neo4j start
You should see the following output at your console, indicating that the process has started:
您应该在控制台上看到以下输出,指示该过程已经开始:
Open up a browser and go to the following URL:
打开浏览器,然后转到以下URL:
http://localhost:7474
It will redirect you to:
它将重定向到:
http://localhost:7474/browser/
You should see the following webpage, which is the Neo4j Browser Console:
您应该看到以下网页,即Neo4j浏览器控制台:
Connect to the database using your own username and password. If you are accessing it for the first time, the credentials are as follows:
使用您自己的用户名和密码连接到数据库。 如果您是首次访问它,则凭据如下:
username
— neo4jusername
— neo4jpassword
— neo4jpassword
— neo4j
After that, you will be prompted to change the password. Once you have logged in to the database, you should see the following user interface:
之后,将提示您更改密码。 登录数据库后,应该会看到以下用户界面:
司机 (Driver)
Neo4j also comes with support for connecting to its database directly via drivers. Based on the latest version, it officially supports the following programming languages:
Neo4j还支持直接通过驱动程序连接到其数据库。 基于最新版本,它正式支持以下编程语言:
.NET
— .NET Standard 2.0.NET
— .NET Standard 2.0Java
—Java 8+ (latest patch releases).Java
Java 8+(最新修补程序版本)。JavaScript
— All LTS versions of Node.JS, specifically the 4.x and 6.x series runtime(s).JavaScript
— Node.JS的所有LTS版本 ,特别是4.x和6.x系列运行时。Python
— CPython 3.5 and above.Python
-CPython 3.5及更高版本。Go
— Work in progress. There is no official release date at the moment.Go
-进行中。 目前没有官方发布日期。
In this tutorial, I am going to use a Python driver for our web application in FastAPI. Kindly check out the following link for more information on the installation steps for the rest of the drivers.
在本教程中,我将为FastAPI中的Web应用程序使用Python驱动程序。 请查看以下链接 ,以获取有关其余驱动程序的安装步骤的更多信息。
It is highly recommended that you create a virtual environment before the installation. Activate your virtual environment and run the following command to install the stable version of Neo4j Python Driver.
强烈建议您在安装之前创建一个虚拟环境。 激活您的虚拟环境并运行以下命令以安装Neo4j Python Driver的稳定版本。
pip install neo4j
If you are looking for the pre-release version, you should run the following command instead:
如果要查找预发行版本,则应改为运行以下命令:
pip install --pre neo4j
FastAPI (FastAPI)
As I have mentioned earlier, our web application is based on FastAPI. Feel free to modify it on your own if you are a Flask user, as you can always migrate it later on. Have a look at my previous article on Migrate Flask to FastAPI Smoothly to find out more about it. In the same terminal, run the following command:
如前所述,我们的Web应用程序基于FastAPI。 如果您是Flask用户,则可以随意对其进行修改,因为您以后可以随时进行迁移。 请参阅我以前的有关平稳地将Flask迁移到FastAPI的文章,以了解更多信息。 在同一终端上,运行以下命令:
pip install fastapi
You will need an ASGI
server as well. The recommended ASGI
server is Uvicorn
. Install it as follows:
您还将需要一台ASGI
服务器。 推荐的ASGI
服务器是Uvicorn
。 如下安装:
pip install uvicorn
用例(人员) (Use Case (Person))
Let’s list down the nodes and relationships in order to model our domain as a graph. To keep things simple and short, let’s say our main character is called Alice and she has a group of friends as follows:
让我们列出节点和关系,以便将我们的域建模为图形。 为简单起见,假设我们的主角叫爱丽丝,她有一群朋友,如下所示:
- Judy朱迪
- Sayaka沙耶香
- Kim Lee金李
- Emily艾米莉
- Daisy雏菊
- Nguyen Hanh阮汉
- Li Ting李婷
Each node represent a single unit with Person
label and their relationships with Alice is denoted as IS_FRIEND_OF
.
每个节点代表一个带有Person
标签的单个单元,它们与Alice的关系表示为IS_FRIEND_OF
。
用例(餐厅) (Use Case (Restaurant))
Alice and her friends often have their meals at the following restaurants:
爱丽丝和她的朋友们经常在以下餐馆用餐:
Korean BBQ
— Located inJurong East
and servesKorean
cuisine.Korean BBQ
-位于Jurong East
,供应Korean
美食。Zen Sushi
— Located inJurong West
and servesJapanese
cuisine.Zen Sushi
位于Jurong West
,供应Japanese
料理。Mala Hot Pot
— Located inJurong North
and servesChinese
cuisine.Mala Hot Pot
-位于Jurong North
,供应Chinese
美食。Dim Sum
— Located inJurong South
and servesChinese
cuisine.Dim Sum
-位于Jurong South
,供应Chinese
美食。Thai Grill
— Located inJurong South
and servesThai
cuisine.Thai Grill
—位于Jurong South
,供应Thai
美食。Pho Street
— Located inJurong East
and servesVietnamese
cuisine.Pho Street
—位于Jurong East
,供应Vietnamese
美食。
There are two relationships here. First, each Restaurant
entity SERVES
a specific Cuisine
entity. Second, each Restaurant entity is LOCATED_IN
a specific Location
entity.
这里有两种关系。 首先,每个Restaurant
实体SERVES
为特定的Cuisine
实体服务。 其次,每个饭店实体都是LOCATED_IN
一个特定的Location
实体。
On top of that, Alice and her friends have their own preferences in the restaurants that they like. The relationships are denoted as Person
entity LIKES
zero or more Restaurant
entities.
最重要的是,爱丽丝(Alice)和她的朋友们在他们喜欢的餐馆里有自己的喜好。 该关系表示为Person
实体, LIKES
零个或多个Restaurant
实体。
2. Neo4j数据库 (2. Neo4j Database)
In this section, we are going to run the graph query language (Cypher) for reading and writing data to our existing database. You can use an existing or a new database for it.
在本节中,我们将运行图查询语言(Cypher),以将数据读写到现有数据库中。 您可以使用现有数据库或新数据库。
清除资料库 (Clear database)
If you already have an existing system and would like to clear it, run the following query:
如果您已经有一个现有系统并想清除它,请运行以下查询:
MATCH (n) DETACH DELETE n
It will remove all existing nodes and their relationships from your database.
它将从数据库中删除所有现有节点及其关系。
创建数据集 (Create dataset)
The following examples shows the way to create two Person
nodes and builds relationships between them:
以下示例显示了创建两个Person
节点并在它们之间建立关系的方法:
CREATE (alice:Person {name:"Alice"})-[:IS_FRIEND_OF]->(judy:Person {name:"Judy"})
Location
node and Cuisine
node can be created as follows:
Location
节点和Cuisine
节点可以按以下方式创建:
CREATE (jurongeast:Location {name:"Jurong East"}), (korean:Cuisine {name:"Korean"})
After that, you can link both nodes together as follows:
之后,可以将两个节点链接在一起,如下所示:
CREATE (koreanbbq:Restaurant {name:"Korean BBQ"})-[:SERVES]->(korean),(koreanbbq)-[:LOCATED_IN]->(jurongeast)
Likewise, you can easily create a relationship between Person
node and Restaurant
via the following query which indicates that judy
likes to eat Korean BBQ
.
同样,您可以通过以下查询轻松地在Person
节点与Restaurant
之间创建关系,该查询表明judy
喜欢吃Korean BBQ
。
CREATE (judy)-[:LIKES]->(koreanbbq)
In fact, you can combine all of them together as a single query. The following gist contains the complete query to create a new dataset for our restaurant recommender system.
实际上,您可以将它们全部组合为一个查询。 以下要点包含用于为我们的餐厅推荐系统创建新数据集的完整查询。
Once you have executed the query, the Database Information should look like this:
执行查询后,数据库信息应如下所示:
得到所有 (Get all)
In order to get all of the data in the database, you can execute the following query:
为了获取数据库中的所有数据,可以执行以下查询:
MATCH (n) RETURN (n)
You should see the following graph in your Neo4j Browser.
您应该在Neo4j浏览器中看到以下图形。
爱丽丝之友 (Friends of Alice)
Run the following query to get the name of Person
nodes that is a friend of Alice. You can notice that there is no direction specified in the query. This implies that it is bi-directional and it will match as long as there exists IS_FRIEND_OF
relationships with Alice.
运行以下查询以获取作为Alice朋友的Person
节点的名称。 您会注意到在查询中没有指定方向。 这意味着它是双向的,并且只要与Alice存在IS_FRIEND_OF
关系就可以匹配。
MATCH (alice:Person {name:"Alice"})-[:IS_FRIEND_OF]-(person)RETURN person.name
On the result page, click on the Text
button and you should see the following result indicates that Alice has 7 friends in total.
在结果页面上,单击“ Text
按钮,您应该看到以下结果表明Alice总共有7个朋友。
餐厅 (Restaurants)
Let’s get more information on just the Restaurant
nodes and their relationships with Location
and Cuisine
nodes.
让我们仅获取有关Restaurant
节点以及它们与Location
和Cuisine
节点的关系的更多信息。
MATCH (location)<-[:LOCATED_IN]-(restaurant)-[:SERVES]->(cuisine)RETURN location, restaurant, cuisine
You should see the following output:
您应该看到以下输出:
特定位置的餐厅 (Restaurants of a specific location)
Let’s say you are only interested in all the restaurants of a specific location, you can query the data as follows:
假设您只对特定位置的所有餐馆感兴趣,则可以按以下方式查询数据:
MATCH (jurongeast:Location {name:"Jurong East"})<-[:LOCATED_IN]-(restaurant)-[:SERVES]->(cuisine)RETURN jurongeast, restaurant, cuisine
It will query all the Restaurant
nodes that are located in Jurong East
.
它将查询位于Jurong East
所有Restaurant
节点。
提供特定美食的餐厅 (Restaurants that serve specific cuisine)
Other than that, let’s say your preference is not about Location
but rather on the Cuisine
. For getting all the restaurants that serve Chinese
cuisine, query it as follows:
除此之外,假设您的偏好不是Location
,而是Cuisine
。 要获取所有提供Chinese
餐厅,请查询以下内容:
MATCH (location)<-[:LOCATED_IN]-(restaurant)-[:SERVES]->(chinese:Cuisine {name: "Chinese"})RETURN location, restaurant, chinese
Upon execution, it will display the following graph in your Neo4j Browser.
执行后,它将在Neo4j浏览器中显示以下图形。
爱丽丝和她的朋友们喜欢的餐厅 (Restaurants that are preferred by Alice and her friends)
Given that Alice is going out with all of her friends and would like to know the best restaurant for their meal, you can recommend a restaurant that they like the most via the following query.
鉴于爱丽丝(Alice)和她所有的朋友一起外出,并且想知道最适合他们用餐的餐厅,您可以通过以下查询来推荐他们最喜欢的餐厅。
MATCH (restaurant:Restaurant)-[:LOCATED_IN]->(location), (restaurant)-[:SERVES]->(cuisine), (person:Person)-[:LIKES]->(restaurant)RETURN restaurant.name, collect(person.name) as likers, count(*) as occurenceORDER BY occurence DESC
I am using two aggregating functions here. The first one is called collect()
which is mostly used to amalgamate multiple results into a single list. In this case, all of the names will be consolidated into a single list as likers
.
我在这里使用两个聚合函数。 第一个称为collect()
,通常用于将多个结果合并到一个列表中。 在这种情况下,所有名称都将作为likers
合并到一个列表中。
Meanwhile, the second aggregating function count()
is used to return the number of matching records. In this case, it will count the number likers
.
同时,第二个聚合函数count()
用于返回匹配记录的数量。 在这种情况下,它将计算likers
人数。
You should get the following result which shows that they can decide either Zen Sushi
or Thai Grill
.
您应该得到以下结果,表明他们可以选择Zen Sushi
或Thai Grill
。
爱丽丝朋友首选的餐厅 (Restaurants that are preferred by Alice’s friends)
Let’s say that Alice is not a picky eater and would like to know just the preferences of her friends. In this case, we need to exclude Alice from the final result. You can choose to set a conditional to exclude Alice or match only her friends. Let’s have a look at the first method which will exclude Alice from the final result. It uses the WHERE
clause together with the <>
negation symbol.
假设爱丽丝不是挑食者,并且只想知道她朋友的喜好。 在这种情况下,我们需要从最终结果中排除Alice。 您可以选择设置条件以排除爱丽丝或仅匹配她的朋友。 让我们看一下第一种方法,该方法将从最终结果中排除Alice。 它将WHERE
子句与<>
否定符号一起使用。
MATCH (restaurant:Restaurant)-[:LOCATED_IN]->(location), (restaurant)-[:SERVES]->(cuisine), (person:Person)-[:LIKES]->(restaurant)RETURN restaurant.name, collect(person.name) as likers, count(*) as occurenceWHERE person.name <> "Alice"ORDER BY occurence DESC
Aside from that, we do it rightly inside MATCH
clause by matching just her friends.
除此之外,我们只匹配她的朋友就可以在MATCH
子句中正确执行此操作。
MATCH (alice:Person {name:"Alice"}), (alice)-[:IS_FRIEND_OF]-(friend), (restaurant:Restaurant)-[:LOCATED_IN]->(location), (restaurant)-[:SERVES]->(cuisine), (friend)-[:LIKES]->(restaurant)RETURN restaurant.name, collect(friend.name) as likers, count(*) as occurenceORDER BY occurence DESC
The following result will be displayed:
将显示以下结果:
爱丽丝的朋友们喜欢的中国餐馆 (Chinese restaurants that are preferred by Alice’s friends)
Assuming that Alice’s friends got tired of the usual cuisines and would like to have Chinese
food today. You can use the following query to get the recommended restaurant.
假设爱丽丝的朋友厌倦了平时的美食,并且想今天吃Chinese
。 您可以使用以下查询来获取推荐的餐厅。
MATCH (alice:Person {name:"Alice"}), (alice)-[:IS_FRIEND_OF]-(friend), (restaurant:Restaurant)-[:LOCATED_IN]->(location), (restaurant)-[:SERVES]->(:Cuisine {name:"Chinese"}), (friend)-[:LIKES]->(restaurant)RETURN restaurant.name, location.name, collect(friend.name) as likers, count(*) as occurenceORDER BY occurence DESC
Based on the result, you can choose either Dim Sum
or Mala Hot Pot
.
根据结果,您可以选择Dim Sum
或Mala Hot Pot
。
位于特定位置且爱丽丝的朋友喜欢的餐厅 (Restaurants located in a specific location that are preferred by Alice’s friends)
Another aspect to factor in is the Location
. Let’s say most of them stay nearby Jurong East
and would like to have a meal around the place. You can provide a recommendation by running the following query:
另一个要考虑的因素是Location
。 假设他们中的大多数人住在Jurong East
附近,并且想在这个地方吃饭。 您可以通过运行以下查询来提供建议:
MATCH (alice:Person {name:"Alice"}), (alice)-[:IS_FRIEND_OF]-(friend), (restaurant:Restaurant)-[:LOCATED_IN]->(location:Location {name:"Jurong East"}), (restaurant)-[:SERVES]->(cuisine), (friend)-[:LIKES]->(restaurant)RETURN restaurant.name, collect(friend.name) as likers, count(*) as occurenceORDER BY occurence DESC
Notice that we have omitted the location name from the result.
注意,我们从结果中省略了位置名称。
一些爱丽丝朋友喜欢的餐厅 (Restaurants that are preferred by a few of Alice’s friends)
Given that Alice
is going out with Judy
and Sayaka
, you can constraint the recommended restaurants via the following query
鉴于Alice
)和Judy
和Sayaka
)在一起,您可以通过以下查询来约束推荐餐厅
MATCH (restaurant:Restaurant)-[:LOCATED_IN]->(location), (restaurant)-[:SERVES]->(cuisine), (person:Person)-[:LIKES]->(restaurant)WHERE person.name = "Judy" OR person.name = "Sayaka"RETURN restaurant.name, collect(person.name) as likers, count(*) as occurenceORDER BY occurence DESC
You will get the best restaurants that are preferred by both Judy
and Sayaka
.
您将获得Judy
和Sayaka
都偏爱的最佳餐厅。
3. Python驱动程序 (3. Python Driver)
In this section, we are going to implement a simple Python module that connects to Neo4j database. Create a new Python file in your working directory. I am going to name it recommender.py
.
在本节中,我们将实现一个连接到Neo4j数据库的简单Python模块。 在您的工作目录中创建一个新的Python文件。 我将其命名为recommender.py
。
进口 (Import)
Add the following import declaration at the top of your file.
在文件顶部添加以下导入声明。
from neo4j import GraphDatabaseimport loggingfrom neo4j.exceptions import ServiceUnavailable
推荐班 (Recommender Class)
Create a new class called Recommender
and fill it with the following functions:
创建一个名为Recommender
的新类,并使用以下函数填充它:
class Recommender: def __init__(self, uri, user, password): self.driver = GraphDatabase.driver(uri, auth=(user, password)) def close(self): self.driver.close()
认证方式 (Authentication)
From version 4 onward, the authentication function has been standardized via the GraphDatabase.driver
function which accepts the following parameters:
从版本4开始,身份验证功能已通过GraphDatabase.driver
函数进行了标准化,该函数接受以下参数:
uri
— Initial address resolution used to bootstrap the system. The local server should use theneo4j://
URI.uri
—用于引导系统的初始地址解析。 本地服务器应使用neo4j://
URI。auth
— A tuple that holds the username and password information.auth
—包含用户名和密码信息的元组。resolver
— Serves as address resolution intercept hook. It accepts a callback function.resolver
—用作地址解析拦截钩。 它接受一个回调函数。
连接到数据库 (Connection to the Database)
Before we continue, let’s explore a little more on how to create a query string and get data from the database. Assuming that your API is responsible for getting a list of names of who is a friend of Alice, we need to write two functions for it.
在继续之前,让我们进一步探讨如何创建查询字符串并从数据库获取数据。 假设您的API负责获取谁是Alice的朋友的姓名列表,我们需要为其编写两个函数。
The first function is a generic function that accepts the input name. It will initialize a session and get data via read_transaction()
function call. You need to pass in a callback function and the parameters to be passed to the callback function.
第一个函数是接受输入名称的通用函数。 它将初始化会话并通过read_transaction()
函数调用获取数据。 您需要传入一个回调函数和要传递给该回调函数的参数。
If your API is responsible for getting records from the database, you need to use the write_transaction()
function instead.
如果您的API负责从数据库获取记录,则需要改用write_transaction()
函数。
The section function will be called by the first function and is mainly responsible for:
section函数将由第一个函数调用,主要负责:
- building a query string based on Cypher from input parameters,根据输入参数基于Cypher构建查询字符串,
- executing the query, and执行查询,以及
- returning the result.返回结果。
The following code snippet illustrates how you can pass parameters into the query string, executing the query via the run()
function. At the end of the function, it will return the result as a list.
以下代码段说明了如何将参数传递到查询字符串中,如何通过run()
函数执行查询。 在函数末尾,它将以列表形式返回结果。
The variable name is marked by adding the dollar sign $
in front of it. It is recommended to declare the staticmethod
decorator on top of it.
通过在变量名称前添加美元符号$
来标记变量名称。 建议在其顶部声明staticmethod
装饰器。
You can test it on your own by adding the following code in the main function:
您可以通过在主函数中添加以下代码来自己进行测试:
if __name__ == "__main__": uri = "neo4j://localhost:7687" user = "neo4j" password = "neo4j" app = Recommender(uri, user, password) print(app.find_friend('Alice')) app.close()
and run the Python file in the terminal:
并在终端中运行Python文件:
python recommender.py
You should get the following output:
您应该获得以下输出:
{'friends': ['Li Ting', 'Nguyen Hanh', 'Daisy', 'Emily', 'Kim Lee', 'Sayaka', 'Judy']}
Recommender.py (Recommender.py)
Let’s add the final touch to our Python file by adding two more functions that are responsible for returning a recommendation based on the following input:
让我们通过添加另外两个函数来最终确定我们的Python文件,这些函数负责根据以下输入返回建议:
cuisine
— Type ofCuisine
preferred by the user.cuisine
-类型Cuisine
优选由用户设定。location
— TheLocation
preferred by the user.location
—用户首选的Location
。person
— Represents a list ofPerson
’s names that are going to join the meal.person
—代表将要加入餐点的Person
名称列表。max
— Determines whether the end result should include just the restaurants with the highest likes (preferred by the participants).max
—确定最终结果是否应仅包括喜欢数最高的餐厅(参与者偏爱)。
You can find the complete code for recommender.py
at the following gist.
你可以找到完整的代码recommender.py
在下面的要点 。
I have added a simple hack to generalized and parameterized the function. It may not be the best solution. Hence, feel free to modify it on your based on your own use cases.
我添加了一个简单的技巧来概括和参数化该功能。 它可能不是最佳解决方案。 因此,可以根据自己的用例随意修改它。
4. FastAPI服务器 (4. FastAPI server)
Now, we are going to set up a FastAPI server that serves as the backend for our web application. Create a new Python file called myapp.py
.
现在,我们将设置一个FastAPI服务器作为Web应用程序的后端。 创建一个名为myapp.py
的新Python文件。
进口 (Import)
Add the following import declaration at the top of the file.
在文件顶部添加以下导入声明。
from fastapi import FastAPIimport recommenderimport atexit
atexit
is part of the Python built-in module which helps to execute registered functions when your application quits. For more information, have a look at my previous tutorial on How to Create Exit Handlers for Your Python App.
atexit
是Python内置模块的一部分,当您的应用程序退出时,该模块有助于执行注册的功能。 有关更多信息,请查看我以前的教程,该教程如何为Python应用程序创建出口处理程序 。
recommender
is the name of the module that we have created earlier assuming that both files reside in the same directory. Modify it accordingly if you are using a different name or have a different hierarchy.
recommender
是我们先前创建的模块的名称,假设两个文件都位于同一目录中。 如果您使用其他名称或具有不同的层次结构,请进行相应的修改。
初始化 (Initialization)
Initialize the following variables which will be used to authenticate to our Neo4j database.
初始化以下变量,这些变量将用于向我们的Neo4j数据库进行身份验证。
uri = "neo4j://localhost:7687"user = "neo4j"password = "neo4j"neo_db = recommender.Recommender(uri, user, password)
退出处理程序 (Exit Handler)
Create a new function that serves to close the connection to the database. We are going to register to atexit
so that it will execute the function on the application exit.
创建一个新功能,用于关闭与数据库的连接。 我们将注册到atexit
以便它将在应用程序出口执行该功能。
def exit_application(): neo_db.close()atexit.register(exit_application)
FastAPI路线 (FastAPI Route)
After that, create a new instance of FastAPI and continue to append the following route inside your Python file.
之后,创建一个新的FastAPI实例,并继续在Python文件中附加以下路由。
app = FastAPI()@app.get('/get-recommedation')async def get_recommedation(cuisine = '', location = '', person = '', max=False): person_list = [] if person == '' else person.split(',') result = neo_db.find_recommendation(cuisine, location, person_list, max) return result
It accepts four query parameters. The person
parameter should be a string that contains the names of the participants. Each name should be separated by a comma. Inside the function, we are going to convert the person
string into a list and call the find_recommendation()
function.
它接受四个查询参数。 person
参数应该是一个包含参与者名称的字符串。 每个名称应以逗号分隔。 在函数内部,我们将把person
字符串转换为列表,然后调用find_recommendation()
函数。
Check out the following gist for the complete code for myapp.py
.
请查看以下要点 ,以获得myapp.py
的完整代码。
运行FastAPI (Running FastAPI)
In order to test it, run the following code to start your FastAPI server:
为了对其进行测试,请运行以下代码以启动您的FastAPI服务器:
uvicorn myapp:app
Then, open up a browser and head over to the following URL:
然后,打开浏览器并转到以下URL:
http://localhost:8000/get-recommedation
You should get the following output:
您应该获得以下输出:
[{"restaurant":"Zen Sushi","likers":["Daisy","Li Ting","Emily","Sayaka"],"occurence":4},{"restaurant":"Thai Grill","likers":["Sayaka","Daisy","Judy","Alice"],"occurence":4},{"restaurant":"Mala Hot Pot","likers":["Li Ting","Nguyen Hanh","Alice"],"occurence":3},{"restaurant":"Dim Sum","likers":["Li Ting","Emily","Alice"],"occurence":3},{"restaurant":"Pho Street","likers":["Kim Lee","Emily","Nguyen Hanh"],"occurence":3},{"restaurant":"Korean BBQ","likers":["Judy","Kim Lee"],"occurence":2}]
查询参数(位置) (Query Parameter (location))
Let’s add a location
input to match only restaurants in Jurong East.
让我们添加一个location
输入以仅匹配裕廊东的餐馆。
http://localhost:8000/get-recommedation?location=Jurong%20East
The result is as follows:
结果如下:
[{"restaurant":"Pho Street","likers":["Kim Lee","Emily","Nguyen Hanh"],"occurence":3},{"restaurant":"Korean BBQ","likers":["Judy","Kim Lee"],"occurence":2}]
查询参数(美食) (Query Parameter (cuisine))
Apart from that, you can specify cuisine
as well.
除此之外,您还可以指定cuisine
。
http://localhost:8000/get-recommedation?cuisine=Chinese
The following data will be displayed on your browser:
以下数据将显示在您的浏览器中:
[{"restaurant":"Dim Sum","likers":["Li Ting","Emily","Alice"],"occurence":3},{"restaurant":"Mala Hot Pot","likers":["Li Ting","Nguyen Hanh","Alice"],"occurence":3}]
查询参数(人) (Query Parameter (person))
Remember that our route has an additional parameter called person which accepts a string of names separated by a comma. Let’s try it out:
请记住,我们的路线还有一个名为person的附加参数,它接受用逗号分隔的名称字符串。 让我们尝试一下:
http://localhost:8000/get-recommedation?person=Alice,Judy,Sayaka
Your end result should look like this:
您的最终结果应如下所示:
[{"restaurant":"Thai Grill","likers":["Sayaka","Judy","Alice"],"occurence":3},{"restaurant":"Korean BBQ","likers":["Judy"],"occurence":1},{"restaurant":"Zen Sushi","likers":["Sayaka"],"occurence":1},{"restaurant":"Mala Hot Pot","likers":["Alice"],"occurence":1},{"restaurant":"Dim Sum","likers":["Alice"],"occurence":1}]
查询参数(最大值) (Query Parameter (max))
By now, you should notice that the returned results consist of records that have at least a single occurence
. In fact, you can modify it to return just the topmost occurence
via the max
parameter. You can use 0
or 1
as well for the input, since Pydantic will parse the value into bool
for you.
到现在为止,您应该注意到返回的结果包含至少occurence
一次的记录。 事实上,你可以修改它返回只是最上面occurence
通过max
参数。 您也可以使用0
或1
作为输入,因为Pydantic会为您将值解析为bool
。
localhost:8000/get-recommedation?person=Alice,Judy,Sayaka&max=True
Setting max to True
will yield the following result:
将max设置为True
将产生以下结果:
[{"restaurant":"Thai Grill","likers":["Sayaka","Judy","Alice"],"occurence":3}]
Congratulations for completing this tutorial. Proceed to the next section for a recap of what we have learned today.
祝贺您完成本教程。 继续下一部分以回顾我们今天所学的内容。
5.结论 (5. Conclusion)
We started off with running Neo4j Console on our browser and installing the necessary modules, such as the Neo4j Python Driver and FastAPI. Besides, we have also outlined an overview of the entities involved in our use case.
我们首先在浏览器上运行Neo4j Console,然后安装必要的模块,例如Neo4j Python Driver和FastAPI。 此外,我们还概述了用例所涉及的实体。
Next, we cleared our database and create a few sample records inside it. The dataset consists of the following nodes: Person
, Location
, Restaurant
, and Cuisine
.
接下来,我们清除了数据库并在其中创建了一些示例记录。 数据集包含以下节点: Person
, Location
, Restaurant
和Cuisine
。
Once we were done with that, we played around with Cypher (Graph Query Language) to get records from the database based on the pattern that we have specified. We tested out a few different patterns that return the recommended restaurants based on our preferences.
完成此操作后,我们将使用Cypher(图形查询语言)来根据指定的模式从数据库中获取记录。 我们测试了几种不同的模式,这些模式会根据我们的偏好返回推荐的餐厅。
We have also implemented a simple module that serves to connect to the database and get records from it. After that, we moved on to establish a FastAPI server as the backend for our web application. Lastly, we tested out a few different use cases on our browser.
我们还实现了一个简单的模块,该模块用于连接数据库并从中获取记录。 之后,我们继续建立FastAPI服务器作为Web应用程序的后端。 最后,我们在浏览器上测试了一些不同的用例。
Thanks for reading this piece. Hope to see you again in the next article!
感谢您阅读本文。 希望在下一篇文章中再见!
翻译自: https://medium.com/better-programming/build-a-restaurant-recommendation-engine-using-neo4j-9d13ebdd4736
neo4j构建算法
http://www.taodudu.cc/news/show-2513070.html
相关文章:
- django oscar_赢得奥斯卡奖之后会发生什么
- drupal 电商网站_为什么小型企业应该为电子商务网站选择Drupal
- jsoncpp操作类
- 使用百度云AI C++SDK在windows上进行在线语音识别
- 二元最佳前缀码_信息与编码系列(二)最优码——Huffman码
- 研究生英语读写译教程下课文译文及课后答案2
- Linux中jsoncpp的编译使用
- mkallcache1.php,distributedCache
- xmake v2.5.9 发布,改进 C++20 模块,并支持 Nim, Keil MDK 和 Unity Build
- Tryhackme-BurpSuite
- SQL Server DMVs in Action 学习笔记
- 解析 DES 加密算法(C语言):
- 计算机视觉论文-2021-11-03
- 数据结构线性表(C++ )
- c++读写json,JsonCpp配置
- Jsoncpp 使用说明
- 分享一个代码合并工具
- 常量类
- 常量表达
- java 斜杠常量_Java基础之常量
- c++语言常量,C++常量(constant)
- 枚举常量
- c语言 常量表达式,常量表达式(什么叫常量表达式)
- java常量 修改_Java 自定义常量
- java 常量pi_Java-常量
- Golang常量无法取地址
- 字面常量
- 详解JVM的常量池
- 0xl c语言中003是整形常量,整型常量
- c语言浮点数常量,C 浮点常量
neo4j构建算法_使用neo4j构建餐厅推荐引擎相关推荐
- neo4j python 算法_python操作neo4j简单实例
一:neo4j是什么 neo4j:Neo4j是一个高性能的,NOSQL图形数据库,有关于更多neo4j的资料出门右拐 二:python操作neo4j的实现 python中neo4j的操作可以利用驱动包 ...
- 今日头条的排名算法_今日头条核心技术“个性推荐算法”揭秘
[IT168 评论]互联网给用户带来了大量的信息,满足了用户在信息时代对信息的需求,也使得用户在面对大量信息时无法从中获得对自己真正有用的那部分信息,对信息的使用效率反而降低了,而通常解决这个问题最常 ...
- neo4j python 算法_图论与图学习(二):图算法
选自towardsdatascience 作者:Maël Fabien机器之心编译参与:熊猫 图(graph)近来正逐渐变成机器学习的一大核心领域,比如你可以通过预测潜在的连接来理解社交网络的结构.检 ...
- rasa算法_使用 Rasa 构建天气查询机器人
本文将介绍如何使用 Rasa NLU 和 Rasa Core 来构建一个简单的带 Web UI 界面的中文天气情况问询机器人(chatbot). 源代码地址 功能 这个机器人可以根据你提供的城市(北京 ...
- 华为开源构建工具_为什么我构建了用于大数据测试和质量控制的开源工具
华为开源构建工具 I've developed an open-source data testing and a quality tool called data-flare. It aims to ...
- 使用python构建向量空间_使用Docker构建Python数据科学容器
人工智能(AI)和机器学习(ML)最近真的火了,并驱动了从自动驾驶汽车到药物发现等等应用领域的快速发展.AI和ML的前途一片光明. 另一方面,Docker通过引入临时轻量级容器彻底改变了计算世界.通过 ...
- cmake 构建路径_基于CMake构建系统的MLIR Example扩展
上一篇文章讲了把pybind11的示例程序嵌入到了MLIR的Example中,但是在构建的过程中有一定运气成分,并不知道具体是怎么通过CMake构建系统编译出的共享库文件.在分析了MLIR各层级的CM ...
- msbuild构建步骤_使用并行构建和多核CPU的MSBuild进行更快的构建
msbuild构建步骤 UPDATE: I've written an UPDATE on how to get MSBuild building using multiple cores from ...
- 使用python构建数据库_使用Python构建(半)自主无人机
使用python构建数据库 They might not be delivering our mail (or our burritos) yet, but drones are now simple ...
- 使用python构建数据库_使用Python构建一个极简主义博客(或者,如何学习停止烦恼和热爱Web开发)。
使用python构建数据库 As of today, I have taken my final examination as an undergraduate student of Physics. ...
最新文章
- Django-restframework 之 Exceptions分析
- 1.2.3 TCP/IP参考模型和五层参考模型
- Python知识点4——if分支与while循环
- Basic Sorting Algorithms
- BZOJ3738 : [Ontak2013]Kapitał
- corosync/openais+pacemaker+drbd+web实现高可用群集
- js 预编译 解释执行 作用域链 闭包
- 如果你喜欢上了一个程序员小伙 献给所有程序员女友(来自ITeye博客的文章 作者:talent2012)...
- LoadRunner参数包含逗号
- Leetcode —— 208. 实现 Trie (前缀树)(Python)
- 一台微型计算机_Linux的上百万行代码,一台新的微型计算机以及Google和Microsoft的更多产品
- 项目管理:文档可测试化
- 1013-----C语言----------几个va_宏函数的使用
- PHP面试题:HTTP中POST、GET、PUT、DELETE方式的区别
- IMDB-WIKI人脸属性数据集解析,dob matlab序列号转为出生日期
- stc单片机id加密c语言,STC单片机使用加密芯片SMEC98SP的加密实例源码
- 解决PMML namespace URI httpwww.dmg.orgPMML-4_4 is not supported
- python 录音vad_语音活性检测器py-webrtcvad安装使用
- tkinter 利器--------pmw模块,里面有很多造好的轮子,有详细的demo
- CentOS 6.8安装Docker V1.0