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 — neo4j

    username — neo4j

  • password — neo4j

    password — 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.0

  • Java —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 in Jurong East and serves Korean cuisine.

    Korean BBQ -位于Jurong East ,供应Korean美食。

  • Zen Sushi — Located in Jurong West and serves Japanese cuisine.

    Zen Sushi位于Jurong West ,供应Japanese料理。

  • Mala Hot Pot — Located in Jurong North and serves Chinese cuisine.

    Mala Hot Pot -位于Jurong North ,供应Chinese美食。

  • Dim Sum — Located in Jurong South and serves Chinese cuisine.

    Dim Sum -位于Jurong South ,供应Chinese美食。

  • Thai Grill — Located in Jurong South and serves Thai cuisine.

    Thai Grill —位于Jurong South ,供应Thai美食。

  • Pho Street — Located in Jurong East and serves Vietnamese 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节点以及它们与LocationCuisine节点的关系的更多信息。

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 SushiThai 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 SumMala 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 )和JudySayaka )在一起,您可以通过以下查询来约束推荐餐厅

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.

您将获得JudySayaka都偏爱的最佳餐厅。

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 the neo4j:// 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 of Cuisine preferred by the user.

    cuisine -类型Cuisine优选由用户设定。

  • location — The Location preferred by the user.

    location —用户首选的Location

  • person — Represents a list of Person’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参数。 您也可以使用01作为输入,因为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.

接下来,我们清除了数据库并在其中创建了一些示例记录。 数据集包含以下节点: PersonLocationRestaurantCuisine

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构建餐厅推荐引擎相关推荐

  1. neo4j python 算法_python操作neo4j简单实例

    一:neo4j是什么 neo4j:Neo4j是一个高性能的,NOSQL图形数据库,有关于更多neo4j的资料出门右拐 二:python操作neo4j的实现 python中neo4j的操作可以利用驱动包 ...

  2. 今日头条的排名算法_今日头条核心技术“个性推荐算法”揭秘

    [IT168 评论]互联网给用户带来了大量的信息,满足了用户在信息时代对信息的需求,也使得用户在面对大量信息时无法从中获得对自己真正有用的那部分信息,对信息的使用效率反而降低了,而通常解决这个问题最常 ...

  3. neo4j python 算法_图论与图学习(二):图算法

    选自towardsdatascience 作者:Maël Fabien机器之心编译参与:熊猫 图(graph)近来正逐渐变成机器学习的一大核心领域,比如你可以通过预测潜在的连接来理解社交网络的结构.检 ...

  4. rasa算法_使用 Rasa 构建天气查询机器人

    本文将介绍如何使用 Rasa NLU 和 Rasa Core 来构建一个简单的带 Web UI 界面的中文天气情况问询机器人(chatbot). 源代码地址 功能 这个机器人可以根据你提供的城市(北京 ...

  5. 华为开源构建工具_为什么我构建了用于大数据测试和质量控制的开源工具

    华为开源构建工具 I've developed an open-source data testing and a quality tool called data-flare. It aims to ...

  6. 使用python构建向量空间_使用Docker构建Python数据科学容器

    人工智能(AI)和机器学习(ML)最近真的火了,并驱动了从自动驾驶汽车到药物发现等等应用领域的快速发展.AI和ML的前途一片光明. 另一方面,Docker通过引入临时轻量级容器彻底改变了计算世界.通过 ...

  7. cmake 构建路径_基于CMake构建系统的MLIR Example扩展

    上一篇文章讲了把pybind11的示例程序嵌入到了MLIR的Example中,但是在构建的过程中有一定运气成分,并不知道具体是怎么通过CMake构建系统编译出的共享库文件.在分析了MLIR各层级的CM ...

  8. msbuild构建步骤_使用并行构建和多核CPU的MSBuild进行更快的构建

    msbuild构建步骤 UPDATE: I've written an UPDATE on how to get MSBuild building using multiple cores from ...

  9. 使用python构建数据库_使用Python构建(半)自主无人机

    使用python构建数据库 They might not be delivering our mail (or our burritos) yet, but drones are now simple ...

  10. 使用python构建数据库_使用Python构建一个极简主义博客(或者,如何学习停止烦恼和热爱Web开发)。

    使用python构建数据库 As of today, I have taken my final examination as an undergraduate student of Physics. ...

最新文章

  1. Django-restframework 之 Exceptions分析
  2. 1.2.3 TCP/IP参考模型和五层参考模型
  3. Python知识点4——if分支与while循环
  4. Basic Sorting Algorithms
  5. BZOJ3738 : [Ontak2013]Kapitał
  6. corosync/openais+pacemaker+drbd+web实现高可用群集
  7. js 预编译 解释执行 作用域链 闭包
  8. 如果你喜欢上了一个程序员小伙 献给所有程序员女友(来自ITeye博客的文章 作者:talent2012)...
  9. LoadRunner参数包含逗号
  10. Leetcode —— 208. 实现 Trie (前缀树)(Python)
  11. 一台微型计算机_Linux的上百万行代码,一台新的微型计算机以及Google和Microsoft的更多产品
  12. 项目管理:文档可测试化
  13. 1013-----C语言----------几个va_宏函数的使用
  14. PHP面试题:HTTP中POST、GET、PUT、DELETE方式的区别
  15. IMDB-WIKI人脸属性数据集解析,dob matlab序列号转为出生日期
  16. stc单片机id加密c语言,STC单片机使用加密芯片SMEC98SP的加密实例源码
  17. 解决PMML namespace URI httpwww.dmg.orgPMML-4_4 is not supported
  18. python 录音vad_语音活性检测器py-webrtcvad安装使用
  19. tkinter 利器--------pmw模块,里面有很多造好的轮子,有详细的demo
  20. CentOS 6.8安装Docker V1.0

热门文章

  1. 2019 计蒜之道 初赛 第三场 阿里巴巴协助征战SARS(python做法,费马小定理+快速幂)
  2. iOS活体人脸识别的Demo和一些思路
  3. SSD和内存数据库技术
  4. 没有apihost什么意思_热文:2021年没有立春什么意思
  5. python求积分面积的几个方法
  6. 如何从 GitHub 上下载指定项目的单个文件或文件夹
  7. 数学建模——摘要写作
  8. 功率因数校正的离线式开关电源设计
  9. 使用手册 煤矿风险管控系统_煤矿风险分级管控手册.doc
  10. 计算机处理器性能排名,2020电脑cpu性能排行榜天梯图