电影智能问答——连接Neo4j提供八个问题接口

一 Neo4j的连接

在这里因为需要依赖Neo4j的部分jar包,所以我们使用Maven来管理各种依赖包。

首先创建一个Maven项目,并在maven项目中的pom.xml中引入

1     <dependency>
2         <groupId>org.neo4j.driver</groupId>
3         <artifactId>neo4j-java-driver</artifactId>
4         <version>1.1.2</version>
5     </dependency>

  

在java中代码如下即可以连接到Neo4j数据库:

 1 import org.neo4j.driver.v1.*;
 2  
 3 import static org.neo4j.driver.v1.Values.parameters;
 4  
 5 Driver driver = GraphDatabase.driver( "bolt://localhost:7687",AuthTokens.basic( "neo4j", "neo4j" ) );
 6 Session session = driver.session();
 7 
 8 //现在已经连接上,创建一个新节点
 9 session.run( "CREATE (a:Person {name: {name}, title: {title}})",
10         parameters( "name", "Arthur", "title", "King" ) );

 

二 设计问题类别

经过贝叶斯分类计算后可以将问题分为几类规范问题,所以需要创建几类规范问题。

二 创建连接并实现问题接口

在之前句子还原之后将提供一个ArrayList<String>类型的数据,ArrayList作为一个长度可变的数据,可确保每次可以传入不同数量的String数据。在ArrayList中,第一个存放问题类型,第二个开始存放关键词(nm电影名,nr演员名,ng类型名)。

所以我们在这部分设计为两个类,一个为main类(之后结合到查询控制器中);另一个为数据访问类,用来存放各种具体方法来访问Neo4j数据库。

1.main类

先定义ArrayList(String)来存放传入参数。在主函数中写一个ArrayList的add方法来进行之后的测试。将传入的ArrayList赋值给本类的ArrayList,即reStrings然后调用receive()方法。

创建一个receive()方法,在其中先获取到传入的ArrayList的第一个数据作为问题类型。

int modelIndex = Integer.valueOf(reStrings.get(0));

然后通过一个switch()case:的方法,由不同的问题类型,调用不同的方法。但是总的来说可以分为两类:返回为单值参数,返回为多值参数。

(1)单值返回

在case后,首先获取到reStrings里的第二个参数,即为关键词。然后调用其相关的方法获得查询结果,如果查询结果不为空则赋值给answer。

1     title = reStrings.get(1);
2     String releaseDate = questionRepository.getMovieReleaseDate(title);
3     if (releaseDate != null) {
4         answer = releaseDate;
5     } else {
6         answer = null;
7     }
8     System.out.println(answer);
9     break;

(2)多值返回

同样在case之后获取到reStrings中的第二个参数,为关键词。然后通过相关的方法查询获得查询结果,但是不同的是返回值为多个参数。所以在赋值给answer时也需要注意多值赋值,先判断返回值的数量是不是非零,非零的话将返回数据转换为String类型然后赋值给answer。

1     title = reStrings.get(1);
2     List<String> types = questionRepository.getMovieTypes(title);                 
3     if (types.size() == 0) {
4     answer = null;
5     } else {
6     answer = types.toString().replace("[", "").replace("]", "");
7     }
8     System.out.println(answer);
9     break;

 2. questionRepository类

该类是用来与数据库进行连接,创建不同的方法从而使不同类型的问题可以按需访问数据库并获取数据。

首先先访问数据库并创建一个访问数据库的实例。

1 static Driver driver = GraphDatabase.driver( "bolt://localhost:7687", AuthTokens.basic( "neo4j", "123456" ) );
2 static Session session = driver.session();

其中传入参数不是本地数据库的7474端口,查阅后发现7474是http端口,而bolt端口是8687。

然后就在类中创建不同问题的不同方法,同样问题可以大概分为三类:单值返回,多值返回和多值输入

(1)单值返回查询

方法中传入参数为关键词,然后调用session访问数据库的实例中访问对应的数据。如下就是在m:Movie中匹配,条件为n.title为title,并且返回电影标题n.title和上映时间n.releasedate,其中将传入的tetle赋值给查询条件中的title。

其中result.next()是查询记录的下一条,result.hasnext是一个布尔值,判断记录是否还有下一条。所以返回记录的下一条,获取记录中的releasedate属性并转换为string类型。

1     public static String getMovieReleaseDate(String title) {
2         StatementResult result = session.run( "match(n:Movie) where n.title={title}" + 
3                 " return n.title as title,n.releasedate as releasedate",
4                 parameters( "title", title ) );
5         return result.next().get("releasedate").asString();
6     }

(2)多值返回查询

多值返回方法的返回参数也是一个List<String>类型,如下,在查询中查询连接表,查询条件为n.title为title值,返回电影类型名称。

因为返回值是一个list<string>类型,所以新建返回参数ans为该类型,然后进行一个while循环,当result.hasnext为真时,表示还有下一条记录,则继续循环。在循环中,将记录一条一条的通过ans.add()加入到在返回参数ans中。

 1     public static List<String> getMovieTypes(String title) {
 2         StatementResult result = session.run( "match(n:Movie)-[r:is]->(b:Genre) where n.title={title}" + 
 3                 " return n.title as title,b.name as name",
 4                 parameters( "title", title ) );
 5         List<String> ans = new ArrayList();
 6         while(result.hasNext())
 7         {
 8             Record record = result.next();
 9             ans.add(record.get("name").asString());
10         }
11         return ans;
12     }

(3)多值输入

 除了以上两种,还有一种多值输入的情况,如“nr这个演员演过的ng类型电影有什么?”这种情况下,关键词就有两个,分别是演员nr和电影属性ng。这个问题的返回值也是多值,所以返回情况和上面的(2)多值返回情况相同,不同是在查询中是通过多值查询。

在查询中有两个条件查询语句结合在一起,并且将两个传入分别付给查询语句的name和gname中。既可以实现多值输入的查询工作。

 1      public static List<String> getActorMoviesByType(String name,String gname) {
 2             StatementResult result = session.run( "match(n:Person)-[:actedin]-(m:Movie) where n.name={name}" + 
 3                     "match(g:Genre)-[:is]-(m) where g.name=~{gname}"+
 4                     " return n.name as name,m.title as title",
 5                     parameters( "name", name,"gname",gname) );
 6             List<String> ans = new ArrayList();
 7             while(result.hasNext())
 8             {
 9                 Record record = result.next();
10                 ans.add(record.get("title").asString());
11             }
12             return ans;
13         }

 

这样就可以通过main来判断问题的类型,由不同的问题类型进行调用不同的questionRepository中的对应方法,来对Neo4j数据库进行相关的查询并返回数据。目前先将数据返回答应在控制台上。

posted @ 2018-07-06 11:03  Mask_D  阅读(1362)  评论(0编辑  收藏  举报