暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Springboot+Neo4j节点与关系的操作(三)

Neo4j权威指南 2021-03-18
1311
前两篇文章Springboot+Neo4j 初级框架搭建(一)Springboot+Neo4j 初级增删改查(二)我们介绍了Springboot集成Neo4j,以及Neo4j单节点的操作。
本篇文章我们就来写写节点与节点中关系的操作!!!话不多说直接开干。
在上篇文章中,我们以公司为例子做了演示,本篇文章我们还是以公司和产品为示例演示。
在生活中公司和产品有很多种关系,比如苹果是一个公司,iPhone12是一个产品,苹果和iPhone12就是一个生产的关系。我们就以这样一个简单的例子来做一个增删改查的操作我可能又要偷懒了。
首先我们在model层创建两个类,一个产品类,一个生产关系类,公司类就不创建了,上篇文章已经有了。
    @NodeEntity(label = "ProductEntry")
    @Data
    public class ProductEntryNode {

    @Id
    private String productEntryId;

    /**
    * 模板id
    */
    private String templateId;

    /**
    * 词条名称
    */
    private String name;

    /**
    * 词条类型 1:产品种类 2:产品类型 3:产品单元
    */
    private String type;
    /**
    * 别名
    */
        private String aliasName;

    /**
    * 简介
    */
        private String introduction;
    }

    创建关系类@RelationshipEntity(type = "Production")表示关系类型;type = "Production"表示是什么关系,例如生产关系,后续查询会用到;@StartNode 表示开始节点;@EndNode 表示结束节点;其他的对象都是关系的属性,比如生产了多少件等。指定了开始节点和结束节点关系就有了方向,表示公司生产产品。这里的结束节点也可以和开始节点是同一个类,比如公司-公司之间是供给关系,那么这里的@EndNode就是CompanyEntryNode,这个容易理解吧

      /**
      * @Author Created by YangMeng on 2021/3/4 14:09
      * 公司->生产 产品关系
      * 指定关系名称为Production
      */
      @Data
      @RelationshipEntity(type = "Production")
      public class ProductionRelationship {

      @Id
      private String uuid;
      @StartNode
      private CompanyEntryNode startNode;

      @EndNode
      private ProductEntryNode endNode;

      /**
      * 收入占比
      */
      private String incomeProportion;

      /**
      * 毛利率
      */
      private String productGross;

      /**
      * 产品单价
      */
      private String productPrice;

      /**
      * 产能
      */
      private String capacity;

      /**
      * 产能利用率
      */
      private String capacityRatio;

      /**
      * 产能占比
      */
      private String capacityProportion;

      }
      分别定义产品和生产关系的dao层结构
        @Repository
        public interface ProductEntryRepository extends Neo4jRepository<ProductEntryNodeString{
        }
          @Repository
          public interface ProductionRelationshipRepository extends Neo4jRepository<ProductionRelationship, String> {
          /**
          * 根据产品获取供应商
          * @param productEntryId
          * @return
          */
          @Query("match (c:CompanyEntry)-[:Production]->(p:ProductEntry) where p.productEntryId={productEntryId} return c.companyEntryId as companyEntryId,c.name as companyName")
          List<DicDto> getCompanyByProductId(String productEntryId);
          }
          在service层我们定义增删改查操作,单节点产品的我们就不做演示了。我们现在只定义生成关系的操作,在关系里我们实现定义两个接口,第一个addProductionRelationship是把公司和产品创建关系连接起来,第二个getCompanyByProductId是根据产品id查询他的供应商,也就是谁生产了它
            /**
            * @Author Created by YangMeng on 2021/3/4 15:29
            */
            public interface ProductionRelationshipService {

            /**
            * 添加公司产品 关系
            *
            * @param startNode
            * @param toNode
            * @return
            */
            ProductionRelationship addProductionRelationship(CompanyEntryNode startNode, ProductEntryNode toNode);

            /**
            * 添加公司产品 关系
            *
            * @param startNodeId
            * @param toNodeId
            * @return
            */
            ProductionRelationship addProductionRelationship(String startNodeId, String toNodeId);

            /**
            * 获取产品的供应商公司
            *
            * @param productEntryId
            * @return
            */
            List<DicDto> getCompanyByProductId(String productEntryId);
            接着实现接口
              @Service
              public class ProductionRelationshipServiceImpl implements ProductionRelationshipService {

              @Autowired
              private ProductionRelationshipRepository productionRelationshipRepository;

              @Autowired
              private CompanyEntryRepository companyEntryRepository;

              @Autowired
              private ProductEntryRepository productEntryRepository;

              /**
              * 添加公司产品 关系
              *
              * @param startNode
              * @param toNode
              * @return
              */
              @Override
              public ProductionRelationship addProductionRelationship(CompanyEntryNode startNode, ProductEntryNode toNode) {
              ProductionRelationship productionRelationship = new ProductionRelationship();
              productionRelationship.setStartNode(startNode);
              productionRelationship.setEndNode(toNode);
              //添加属性
                      productionRelationship.setUuid(UuidUtils.generate());
              ProductionRelationship save = productionRelationshipRepository.save(productionRelationship);
              return save;
              }

              /**
              * 添加公司产品 关系
              *
              * @param startNodeId
              * @param toNodeId
              * @return
              */
              @Override
              public ProductionRelationship addProductionRelationship(String startNodeId, String toNodeId) {
              Optional<CompanyEntryNode> byId = companyEntryRepository.findById(startNodeId);
              Optional<ProductEntryNode> byId1 = productEntryRepository.findById(toNodeId);
              if (byId.isPresent() && byId1.isPresent()) {
              return addProductionRelationship(byId.get(), byId1.get());
              }
              return new ProductionRelationship();
              }

              /**
              * 获取产品的供应商公司
              *
              * @param productEntryId
              * @return
              */
              @Override
              public List<DicDto> getCompanyByProductId(String productEntryId) {
              return productionRelationshipRepository.getCompanyByProductId(productEntryId);
              }
              }
              创建controller调用
                @RestController
                @RequestMapping(value = "productionRelationship")
                @Slf4j
                public class ProductionRelationshipController {

                @Autowired
                private ProductionRelationshipService productionRelationshipService;

                /**
                * 关联公司产品 关系
                *
                * @param startId
                * @param endId
                * @return
                */
                @GetMapping(value = "addRelationship")
                public WebResInfo addRelationship(String startId, String endId) {
                log.info("addRelationship->startId:{},endId:{}", startId, endId);
                WebResInfo webResInfo = new WebResInfo();
                try {
                webResInfo.setCode(WebResCode.Successful);
                ProductionRelationship productionRelationship = productionRelationshipService.addProductionRelationship(startId, endId);
                webResInfo.setData(productionRelationship);

                } catch (Exception e) {
                log.error("addRelationship error:{}", e);
                webResInfo.setCode(WebResCode.Server_Bug_Exception);
                webResInfo.setMessage(e.getMessage());
                }
                return webResInfo;
                }

                /**
                * 根据产品获取供应商信息
                *
                * @param productEntryId
                * @return
                */
                @GetMapping(value = "getCompanyByProductId")
                public WebResInfo getCompanyByProductId(String productEntryId) {
                log.info("getCompanyByProductId->productEntryId:{}", productEntryId);
                WebResInfo webResInfo = new WebResInfo();
                try {
                webResInfo.setCode(WebResCode.Successful);
                List<DicDto> companyByProductId = productionRelationshipService.getCompanyByProductId(productEntryId);
                webResInfo.setData(companyByProductId);
                } catch (Exception e) {
                log.error("getCompanyByProductId error:{}", e);
                webResInfo.setCode(WebResCode.Server_Bug_Exception);
                webResInfo.setMessage(e.getMessage());
                }
                return webResInfo;
                }
                我们新增一个公司“阿里巴巴”companyEntryId为2,在新增一个产品“宝马X5”productEntryId为6,然后我们创建他们两个的关系用postman调用

                这样一个关系就创建好了,然后看看我们的数据库已经创建好了关系

                基于以上关系的创建,现在我们查找生产iPhone的公司有哪些
                   @Query("match (c:CompanyEntry)-[:Production]->(p:ProductEntry) where p.productEntryId={productEntryId} return  c.companyEntryId as companyEntryId,c.name as companyName")
                  List<DicDto> getCompanyByProductId(String productEntryId);

                  这里就是查询产品id为{productEntryId}的对应的公司,并且指定了关系是Production,然后就可以查出来苹果公司了。具体请求大家试试就好了

                  本篇主要介绍关系类型,相信大家有了一定的了解,其实neo4j里最主要还是语义化查询,有了关系我们就可以进行这样一系列查询操作,比如我搜索“iPhone12的生产商是谁可以查询产品节点是iPhone,对应关系是生产,然后就出来了苹果公司了。这只是其中一小部分,后续还有很多。     彩蛋下篇文章我们来讲讲Springboot同时绑定neo4j和mysql两个数据源。    

                  有问题大家回复我。

                  文章转载自Neo4j权威指南,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

                  评论