`

<转>Neo4j结合Spring Data Graph的例子

阅读更多

 

原文地址:http://www.openfetion.com/category/neo4j.aspx

在spring中使用neo4j

clock 四月 19, 2010 08:07 by author Terry

从neo4j官方网站http://neo4j.org/下载neo4j-apoc包,或者自己获取源码自行打包也可。
我使用的是java开发工具是Spring Tool Suite,新建一个spring web mvc项目,模板引擎使用velocity(velocity.apache.org),web.xml配置:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    id="attentiondb" version="2.5">
    <display-name>attentiondb</display-name>

    <!--
        Enables clean URLs with JSP views e.g. /welcome instead of
        /app/welcome
    -->
    <filter>
        <filter-name>UrlRewriteFilter</filter-name>
        <filter-class>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>UrlRewriteFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <!-- Handles all requests into the application -->
    <servlet>
        <servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>
                /WEB-INF/spring/app-config.xml
            </param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
        <url-pattern>/attentiondb/*</url-pattern>
    </servlet-mapping>

</web-app>
在/WEB-INF/spring/app-config.xml中配置neo4j bean(这里需要注意spring 2.5与3.0的区别,3.0中使用map元素代替util:map元素):
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">

    <!--
        Scans the classpath of this application for @Components to deploy as
        beans
    -->
    <context:component-scan base-package="attentiondb" />
    
    <bean id="graphDbService" class="org.neo4j.kernel.EmbeddedGraphDatabase"
        init-method="enableRemoteShell" destroy-method="shutdown">
        <constructor-arg index="0" value="d://attentiondb" />
        <constructor-arg index="1">
            <map>
                <entry key="create" value="false"/>
                <entry key="neostore.nodestore.db.mapped_memory" value="20M"/>
                <entry key="neostore.propertystore.db.mapped_memory" value="90M"/>
                <entry key="neostore.nodestore.db.mapped_memory" value="1M"/>
                <entry key="neostore.nodestore.db.mapped_memory" value="1M"/>
                <entry key="neostore.nodestore.db.mapped_memory" value="130M"/>
                <entry key="neostore.nodestore.db.mapped_memory" value="100M"/>
            </map>
        </constructor-arg>
    </bean>
    <bean id="indexService" class="org.neo4j.index.lucene.LuceneIndexService"
        destroy-method="shutdown">
        <constructor-arg index="0" ref="graphDbService" />
    </bean>

    <bean id="velocityConfig"
        class="org.springframework.web.servlet.view.velocity.VelocityConfigurer">
        <property name="resourceLoaderPath" value="/WEB-INF/views/" />
    </bean>

    <bean id="viewResolver"
        class="org.springframework.web.servlet.view.velocity.VelocityViewResolver">
        <property name="cache" value="true" />
        <property name="prefix" value="" />
        <property name="suffix" value=".vm" />
    </bean>

    <!-- Application Message Bundle -->
    <bean id="messageSource"
        class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
        <property name="basename" value="/WEB-INF/messages/messages" />
        <property name="cacheSeconds" value="0" />
    </bean>

    <!-- Configures Spring MVC -->
    <import resource="mvc-config.xml" />

</beans>

第一个打分



neo4j处理好友关系

clock 四月 1, 2010 16:44 by author Terry

在实际业务中,我们经常遇到这样的场景,比如查找好友的好友。处理此类业务,neo4j体现出了方便快捷强大的功能。
比如我们有九个人:
Id Name
1  梁1
2  梁2
3  梁3
4  梁4
5  梁5
6  梁6
7  梁7
8  梁8
9  梁9

其中:梁1、梁2认识所有的人,梁9认识梁1、梁2、梁8
我们要实现查找梁9的好友的好友(不包括自身和直接好友)。
首先定义好友关系枚举:
public enum FriendRelationTypes implements RelationshipType {
        KNOWS
    }
创建上述好友关系graph database:
ArrayList<Node> nodes = new ArrayList<Node>(9);

        Map<String, String> props = new HashMap<String, String>();
        // props.put("create", "false");

        GraphDatabaseService graphDb = new EmbeddedGraphDatabase("var/base",
                props);
        
        Transaction tx = graphDb.beginTx();

        try {
            for (int i = 0; i < 9; i++) {
                Node node = graphDb.createNode();
                node.setProperty("Id", i + 1);
                node.setProperty("Name", "梁" + i);

                nodes.add(node);
            }

            Node node1 = nodes.get(0);
            Node node2 = nodes.get(1);
            Node node9 = nodes.get(8);

            for (int i = 2; i < 9; i++) {
                Node node = nodes.get(i);

                node.createRelationshipTo(node1, FriendRelationTypes.KNOWS);
                node.createRelationshipTo(node2, FriendRelationTypes.KNOWS);
            }

            nodes.get(7).createRelationshipTo(node9, FriendRelationTypes.KNOWS);

            tx.success();

        } catch (Exception ex) {
            ex.printStackTrace();
        } finally {
            tx.finish();
            graphDb.shutdown();
        }
显示所有的好友,查找梁9的好友并显示:
Map<String, String> props = new HashMap<String, String>();
        props.put("create", "false");

        GraphDatabaseService graphDb = new EmbeddedGraphDatabase("var/base",
                props);

        Transaction tx = graphDb.beginTx();

        try {
            Iterable<Node> nodes = graphDb.getAllNodes();

            for (Node node : nodes) {
                if (node.hasProperty("Id")) {
                    System.out.println("NodeId: " + node.getId() + " Id: "
                            + node.getProperty("Id") + " Name:"
                            + node.getProperty("Name"));
                }
            }

            Node node = graphDb.getNodeById(9);

            Traverser friends = node.traverse(Traverser.Order.BREADTH_FIRST,
                    StopEvaluator.END_OF_GRAPH, new ReturnableEvaluator() {
                        public boolean isReturnableNode(TraversalPosition pos) {
                            System.out.println(pos.depth());

                            return pos.depth() != 1 && pos.notStartNode();
                        }
                    }, FriendRelationTypes.KNOWS, Direction.BOTH);

            for (Node friend : friends) {
                System.out.println("Id:" + friend.getProperty("Id") + " Name:"
                        + friend.getProperty("Name"));
            }

            tx.success();

        } finally {
            tx.finish();
            graphDb.shutdown();
        }
在这里我们可以看到Traverser的简单应用。在neo4j查找中,需要先找到一个根节点,然后再这个根节点上创建Traverser来进行各种查询。

第一个打分



neo4j初体验

clock 三月 31, 2010 03:51 by author Terry

neo4j(http://neo4j.org/)一个开源的图数据库graph database。neo4j是基于磁盘文件、内嵌、支持java事务JTS,用于存储图结构数据的数据库引擎。具体的资料可以查看官方网站。
neo4j的存储结构中重点的就是Node(节点)和Relationship(关系)。Node与Node之间通过Relationship连接,Node与Node之间可以具有多种关系,但是两个Node不能相同。
下面通过一个具体的业务来演示一下neo4j的简单使用。
我们需要来存储用户与用户之间都有过什么关系,关系之间有什么样的权重,这样通过用户之间的关系和关系的权重,在此基础上我们可以分析用户之间的关注度。在数据中是这样存储的:
relation关系表,用来枚举用户之间可能存在的关系,及关系的自定义权重
1    发表文章评论    3
2    回复文章评论    1
3    喜欢文章    1
4    文章点名    50
5    留言    10
6    回复留言    3
7    评论留言飞语    5
8    回复留言飞语评论    5
9    收藏留言飞语    3
10    评论图片    3
11    回复图片评论    3
12    图片圈人    20
13    分享     20
14    站内信    2
15    回复站内信    2
graphs用户关系系表,存储两个用户之间都具有什么样的关系。有三个字段:BeginUserId开始用户Id、EndUserId结束用户Id、Reason原因。其中Reason是xml格式数据,记录了用户Id为EndUserId对用户Id为BeginUserId发生过什么行为,产生过什么样的关系,如1490578    18129607    21    <a t="3" e="1" /><a t="13" e="20" />,表明用户18129607对用户1490578曾经回复留言、喜欢文章,e可以次数以表示权重。
以下是如何通过neo4j来创建此业务的graph database,实际graphs表中有600万左右的数据,我们为了演示只取前1000条,并且只是通过neo4j kernel核心包来创建。
创建AttentionRelationTypes枚举,实现接口RelationshipType,这是必须的。节点直接的Relationship是通过RelationshipType的不同名称来定义并区分的。
package easynet.neo4j;

import org.neo4j.graphdb.RelationshipType;

/*
 * 关注关系
 */
public enum AttentionRelationTypes implements RelationshipType {
    PublishedComments, ReplyToComment, FavoriteArticle, ArticleMention, Message, ReplyToMessage, CommentOnMood, ReplyToMoodComments, FavoriteMood, CommentOnPicture, ReplyToPictureComments, CirclePicture, Share, SiteMessage, ReplyToSiteMessage
}
很重要的一点,由于neo4j是自己维护Node的Id,我们不能把UserId当作Node的Id,而只能作为一个Node的Property。但是因为我们在业务上需要保证作为用户Node的唯一性,所以创建一个用来维护UserId与NodeId的对应关系表:usernode(有两个字段UserId、NodeId)。定义一个类NodeStore用来分装此操作。
package easynet.neo4j;

import java.sql.*;

import net.sourceforge.jtds.jdbcx.*;

public class NodeStore {
    private JtdsDataSource dataSource = null;
    private String insertQuery = "{call [UserNode_Create](?,?)}";
    private String getNodeIdQuery = "{call [UserNode_GetNodeIdByUserId](?)}";

    public NodeStore(JtdsDataSource dataSource) {
        this.dataSource = dataSource;
    }

    public void store(int userId, long nodeId) throws SQLException {
        Connection con = dataSource.getConnection();
        CallableStatement cst = con.prepareCall(insertQuery);

        cst.setInt(1, userId);
        cst.setLong(2, nodeId);

        cst.execute();

        cst.close();
    }

    public long getNodeIdByUserId(int userId) throws SQLException {
        int nodeId = 0;

        Connection con = dataSource.getConnection();
        CallableStatement cst = con.prepareCall(getNodeIdQuery);

        cst.setInt(1, userId);

        ResultSet rs = cst.executeQuery();

        while (rs.next()) {
            nodeId = rs.getInt("NodeId");
        }

        cst.close();

        return nodeId;
    }
}
下面就是具体通过neo4j创建graph database的代码了:
package easynet.neo4j;

import java.io.*;
import java.sql.*;
import java.util.*;
import org.w3c.dom.*;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import javax.xml.parsers.*;

import net.sourceforge.jtds.jdbcx.*;

import org.neo4j.graphdb.*;
import org.neo4j.graphdb.Node;
import org.neo4j.kernel.*;
import org.neo4j.kernel.impl.traversal.*;

public class AttentionRelationShell {

    /**
     * 处理关注关系
     * 
     * @throws SQLException
     */
    public static void main(String[] args) {
        JtdsDataSource dataSource = new JtdsDataSource();
        dataSource.setServerName("192.168.1.100");
        dataSource.setPortNumber(1433);
        dataSource.setDatabaseName("yadong_temp");
        dataSource.setUser("sa");
        dataSource.setPassword("devterry");

        NodeStore nodeStore = new NodeStore(dataSource);

        long beginTime = System.currentTimeMillis();
        System.out.println("开始创建...");

        Map<String, String> props = new HashMap<String, String>();
        // props.put("create", "false");

        GraphDatabaseService graphDb = new EmbeddedGraphDatabase("var/base",
                props);

        try {

            Connection con = dataSource.getConnection();
            Statement st = con.createStatement();
            ResultSet rs = st
                    .executeQuery("SELECT [BeginUserId],[EndUserId],[Reason] FROM [graphs]");

            while (rs.next()) {
                int beginUserId = rs.getInt("BeginUserId");
                int endUserId = rs.getInt("EndUserId");
                String reason = rs.getString("Reason");

                System.out.println("beginUserId:" + beginUserId
                        + " endUserId:" + endUserId);

                Node beginUserNode = null;
                Node endUserNode = null;

                Transaction tx = graphDb.beginTx();

                try {
                    long beginNodeId = nodeStore.getNodeIdByUserId(beginUserId);
                    long endNodeId = nodeStore.getNodeIdByUserId(endUserId);

                    if (beginNodeId != 0) {
                        beginUserNode = graphDb.getNodeById(beginNodeId);
                    } else {
                        beginUserNode = graphDb.createNode();
                        beginUserNode.setProperty("UserId", beginUserId);

                        nodeStore.store(beginUserId, beginUserNode.getId());
                    }

                    if (endNodeId != 0) {
                        endUserNode = graphDb.getNodeById(endNodeId);
                    } else {
                        endUserNode = graphDb.createNode();
                        endUserNode.setProperty("UserId", endUserId);

                        nodeStore.store(endUserId, endUserNode.getId());
                    }

                    try {
                        DocumentBuilderFactory factory = DocumentBuilderFactory
                                .newInstance();
                        DocumentBuilder builder = factory.newDocumentBuilder();
                        StringReader sr = new StringReader("<relation>"
                                + reason + "</relation>");
                        InputSource is = new InputSource(sr);
                        Document doc = builder.parse(is);
                        NodeList nodes = doc.getElementsByTagName("a");

                        // 创建用户Node之间的Relationship
                        for (int i = 0; i < nodes.getLength(); i++) {
                            org.w3c.dom.Node node = nodes.item(i);

                            NamedNodeMap attributes = node.getAttributes();

                            int realtionTypeId = Integer.parseInt(attributes
                                    .getNamedItem("t").getNodeValue());
                            int weight = Integer.parseInt(attributes
                                    .getNamedItem("e").getNodeValue());

                            AttentionRelationTypes relationTypes = AttentionRelationTypes.PublishedComments;

                            switch (realtionTypeId) {
                            case 1:
                                relationTypes = AttentionRelationTypes.PublishedComments;
                                break;
                            case 2:
                                relationTypes = AttentionRelationTypes.ReplyToComment;
                                break;
                            case 3:
                                relationTypes = AttentionRelationTypes.FavoriteArticle;
                                break;
                            case 4:
                                relationTypes = AttentionRelationTypes.ArticleMention;
                                break;
                            case 5:
                                relationTypes = AttentionRelationTypes.Message;
                                break;
                            case 6:
                                relationTypes = AttentionRelationTypes.ReplyToMessage;
                                break;
                            case 7:
                                relationTypes = AttentionRelationTypes.CommentOnMood;
                                break;
                            case 8:
                                relationTypes = AttentionRelationTypes.ReplyToMoodComments;
                                break;
                            case 9:
                                relationTypes = AttentionRelationTypes.FavoriteMood;
                                break;
                            case 10:
                                relationTypes = AttentionRelationTypes.CommentOnPicture;
                                break;
                            case 11:
                                relationTypes = AttentionRelationTypes.ReplyToPictureComments;
                                break;
                            case 12:
                                relationTypes = AttentionRelationTypes.CirclePicture;
                                break;
                            case 13:
                                relationTypes = AttentionRelationTypes.Share;
                                break;
                            case 14:
                                relationTypes = AttentionRelationTypes.SiteMessage;
                                break;
                            case 15:
                                relationTypes = AttentionRelationTypes.ReplyToSiteMessage;
                                break;
                            }

                            Relationship relationShip = endUserNode
                                    .createRelationshipTo(beginUserNode,
                                            relationTypes);
                            relationShip.setProperty("weight", weight);
                        }
                    } catch (Exception ex) {
                        ex.printStackTrace();
                    }
                } finally {
                    tx.success();
                    tx.finish();
                }
            }
        } catch (SQLException ex) {
            ex.printStackTrace();
        } finally {
            graphDb.shutdown();
        }

        System.out.println("完成 共用时:"
                + (System.currentTimeMillis() - beginTime));
    }
}

 

分享到:
评论
1 楼 pizi18 2012-03-15  
您好,想请教一下楼主,neo4j数据库在前台是用什么样的方式展现的吗?有没有一些例子可以学习一下的,谢谢了

相关推荐

    采用java操作neo4j数据库源码

    在实际应用中,为了提高性能和灵活性,可能需要结合Spring Data Neo4j等框架,它们提供了更高级别的抽象,使得与Neo4j的交互更加便捷。 总结来说,通过Java操作Neo4j数据库涉及到的关键知识点包括: 1. 引入 Neo4j...

    spring-data-neo4j

    - **Querydsl扩展**:Querydsl是一种类型安全的查询构建器,可以与Spring Data Neo4j结合使用。 - **Web支持**:提供了RESTful Web服务的支持。 - **Repository填充器**:用于自动填充Repository实例。 - **遗留Web...

    spring-data-graph-1.0.0.RELEASE.zip

    Spring Data Graph是基于TinkerPop3框架构建的,TinkerPop是一个开源的图数据库抽象层,允许开发者通过统一的API来操作各种图数据库,如Neo4j、JanusGraph等。Spring Data Graph提供了Spring的注解驱动和Repository...

    neo4j最全面指南以及springboot+java驱动不用编写复杂语句

    &lt;artifactId&gt;neo4j-java-driver&lt;/artifactId&gt; &lt;version&gt;4.4.2&lt;/version&gt; &lt;/dependency&gt; ``` ##### 2. 配置连接 - 在 `application.properties` 或 `application.yml` 文件中配置连接信息: ```properties ...

    Spring Data:Spring Data Modern Data Access for Enterprise Java

    7. Neo4j: A Graph Database 8. Redis: A Key/Value Store Part IV. Rapid Application Development 9. Persistence Layers with Spring Roo 10. REST Repository Exporter Part V. Big Data 11. Spring for Apache ...

    SpringData.zip

    提供多个常用场景下的简单封装Document - 集成文档数据库:CouchDB 和 MongoDB 并提供基本的配置映射和资料库支持Graph - 集成 Neo4j 提供强大的基于 POJO 的编程模型Graph Roo AddOn - Roo support for Neo4jJDBC ...

    spring-data-neo4j-cross-store-3.0.1.RELEASE.zip

    【标题】"Spring Data Neo4j Cross Store 3.0.1.RELEASE.zip" 是一个包含Spring Data Neo4j跨存储支持的版本发布。Spring Data是Spring框架的一部分,它简化了对各种数据存储的访问,包括关系型数据库、NoSQL数据库...

    spring-graph-neo4j:Neo4j的春天

    标题中的“spring-graph-neo4j:Neo4j的春天”暗示了我们将探讨Spring框架与图数据库Neo4j的结合使用。在Java开发领域,Spring框架是一个广泛使用的开源框架,它提供了一整套用于构建企业级应用的服务和工具。而Neo4j...

    spring data API

    Spring Data 项目的目的是为了简化构建基于 Spring 框架应用的数据访问计数,包括非关系数据库、Map-Reduce 框架、云数据服务等等;另外也包含对关系数据库的访问支持。 Spring Data 包含多个子项目: Commons - ...

    Neo4j High Performance(PACKT,2015)

    Study the in-built graph algorithms for better traversals and discover Spring-Data-Neo4j Look under the hood of Neo4j, covering concepts from the core classes in the source to the internal storage ...

    Neo4j开发手册

    开发过程中,可以使用Spring Data Neo4j、Py2neo等库简化操作。此外,Neo4j Browser是一个交互式的图形界面,便于数据探索和调试。 九、高可用性与扩展性 对于大型项目,Neo4j提供了高可用性解决方案,如复制...

    Manning.Spring.in.Action.4th.Edition.2014.11.epub

    2.4.2. Declaring a simple &lt;bean&gt; 2.4.3. Initializing a bean with constructor injection 2.4.4. Setting properties 2.5. Importing and mixing configurations 2.5.1. Referencing XML configuration in Java...

    Spring-neo4j

    在实际项目中,Spring-Neo4j的使用需要结合Spring Boot、Spring Data等其他Spring生态组件,通过合理的配置和编程模型,可以构建出高效、可扩展的图数据库应用。同时,开发者还需要了解Neo4j的特性和最佳实践,以便...

    neo4j安装配置入门教程

    Neo4j是一款强大的图形数据库,尤其适用于处理复杂的关系和网络...同时,还可以利用各种第三方库和工具,如Spring Data Neo4j,来简化开发流程。随着对Neo4j的理解深入,你会发现它在处理复杂数据结构时的强大之处。

    图数据库图数据库图数据库.pptx

    SpringBoot 可以整合 Neo4j,使用 Spring-boot-starter-data-neo4j 依赖项。Neo4j 提供了丰富的 API,支持 Java、Python、JavaScript 等语言。 五、图数据库在项目中的应用 图数据库在项目中的应用包括社交网络...

    知识图:Neo4j数据可视化

    使用d3.js可视化知识图谱============================数据目录bg.jpg可视化背景图片数据CircularPartition.json基线圆形分区图工具...graph-webCSV文件导入接口 data.lab.knowledgegraph.service.DataServiceImplTest

    基于springBoot的知识图库.zip

    1. **数据存储**:知识图谱通常使用图数据库如Neo4j或JanusGraph存储,Spring Boot可以方便地与这些数据库集成,通过JPA或自定义Repository接口进行操作。 2. **RESTful API**:Spring Boot支持快速构建RESTful服务...

    mock-imdb-app

    模拟-imdb-app acts as imdb api using imdb data set[] ...Neo4J (Graph Database) 运行应用 - docker run --publish=7474:7474 --publish=7687:7687 -e 'NEO4J_AUTH=neo4j/secret' neo4j:4.1 - run app

    情感分析微博服务示例:一个示例应用程序,演示了如何构建图形处理平台来分析Twitter上的情感影响源

    情绪分析Twitter微服务示例一个示例应用程序,演示了...Spring启动服务排名仪表板发现服务配置服务Twitter爬虫支持服务Neo4j(螺栓) RabbitMQ(AMQP) Twitter API(HTTP) Google Cloud Language API(HTTP)图处理平

Global site tag (gtag.js) - Google Analytics