Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 精品国产日韩久久亚洲,日韩中文字幕视频在线观看,欧美性色黄大片a级毛片视频

          整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          JS寫的服務端,如何連接Mysql數據庫,實現增刪查改功能

          一篇文章我給大家說明了如何從零開始搭建一個node的服務端框架,我們用到了Egg框架。Egg框架我不再過多介紹,如果有小伙伴想了解,可以回去看我以前寫的文章,會有相關的介紹。這次我將在上次搭建的框架上進行延伸,講一下如果用Egg框架連接數據庫,并且實現對數據的增刪查改。接下來我們直接進入主題。

          安裝數據庫插件

          我本次選用的數據庫是MySQL。所以我們安裝Egg官方的數據庫插件即可,首先我們安裝插件 egg-mysql 。我們在項目根目錄打開命令提示符,輸入命令行:npm i --save egg-mysql ?;剀嚨却寮螺d安裝完成。

          npm i --save egg-mysql

          配置插件

          命令行下載安裝插件完成后,我們下一步的工作就是在項目中開啟并配置egg-mysql插件。具體操作如下:

          首先我們要在項目中開啟數據庫。找到項目中的/config/plugin.js文件我們需要在里面添加幾行代碼,如下所示。

          //開啟數據庫插件
            mysql : {
              enable: true,
              package: 'egg-mysql',
            }

          然后我們還要在 config/config.default.js 中配置各個環境的數據庫連接信息。具體配置如下。

          //添加數據庫連接信息
            config.mysql = {
              // 單數據庫信息配置
              client: {
                // host
                host: 'localhost',
                // 端口號
                port: '3306',
                // 用戶名
                user: 'root',
                // 密碼
                password: '123456',
                // 數據庫名
                database: 'testdb',
              },
              // 是否加載到 app 上,默認開啟
              app: true,
              // 是否加載到 agent 上,默認關閉
              agent: false,
            };

          到此步驟我們的數據庫插件已經安裝完成并且配置好了。那我們怎么實現數據的增刪查改呢?大家請繼續往下看。

          數據操作-新增用戶

          首先我們看一下怎么新增數據。我們在mysql的testdb實例中新建一個user空表。如下圖所示。

          我們的egg框架也遵循MVC的架構所以我們一般會在service層里面寫我們邏輯處理的代碼,而controller層則是獲取前端數據,回傳數據的控制層。所以我們操作數據庫的代碼是寫在service文件夾里面的。

          我們在app/service文件夾里面新建一個user.js文件。在里面寫個新增用戶的方法,該方法就是把數據存到數據庫中。具體代碼如下。

          const Service = require('egg').Service;
          
          class UserService extends Service {
          
            //新增用戶data是有controller層傳遞過來的數據記錄。
            async addUser(data) {
          
              const {ctx, app} = this;
              let result = {};
              try {
                data.id = 0;//定義id=0,因為數據庫已經設置id為主鍵,并且自增。所以只需要賦值0即可。
                // 在 user 表中,插入前端提交上來的數據記錄
                const info = await app.mysql.insert('user', data); 
            
                //插入成功后。
                if(info.affectedRows === 1){
                  //給前端返回一個Json的對象
                  result = {
                    state: 0, //自定義的狀態碼
                    msg: "添加成功", //返回的消息
                    data: info.insertId, //新增的記錄的id
                  }
                }
          
              } catch (err) {
                //插入數據失敗的返回結果
                result = {
                  state: 1, 
                  msg: err,
                  data: null,
                }
              }
              
              return result
            }
          };
          module.exports = UserService;

          然后我們在app/controller文件夾里新建一個user.js文件。在這里我們需要獲取前端提交上來的數據,并且將數據處理的結果返回給前端。具體代碼如下。

          'use strict';
          
          const Controller = require('egg').Controller;
          /**
           * @Controller 用戶管理
           */
          class UserController extends Controller {
          
            /**
            * @summary 新增用戶
            * @router post /user/add
            * @request body userAddRequest 
            * @response 200 
            */
            async addUser() {
              const { ctx } = this;
          
              //通過ctx.request.body的方式,可以獲取到前端post方式提交上來的數據
              const data = ctx.request.body;
          
              //調用service層的addUser方法。并且返回相應的結果
              const userInfo = await ctx.service.user.addUser(data);
              
              //向前端接口響應數據。
              ctx.body = userInfo;
            }
          
          }
          
          module.exports = UserController;

          最后我們定義一個路由,讓前端請求訪問此路由??蚣軙O聽路由是否被訪問,如果被訪問了則會調用我們定義在controller層的新增用戶的方法。我們在app/router.js文件中添加如下代碼,即可完成路由的定義。

          //新增用戶路由
            router.post('/user/add', controller.user.addUser);

          完成這步驟后,我們一個新增用戶的功能就已經完成了。接下里我們就測試一下它的實際效果。我們運行命令:npm run dev。啟動項目,然后打開網頁http://127.0.0.1:7001,可以直接在swagger-ui.html頁面中進行測試。結果如下圖所示。

          經過測試,數據已經添加完成。所以數據庫連接也是正常的。

          本次分享暫時先告一段落。請各位小伙伴抬起你們發財的小手,點個贊唄。下次我將會進行和大家分享對數據查改刪的方法。關注我?。?!更多精彩分享不迷路。

          日客戶要求表內的數據依據某種分組生成HTML頁面進行展示,一般處理這種需求直接上編程工具就好了,從數據庫里讀取數據,根據規則生成字符串,最后將字符串寫出到文件。由于需求比較急,作為數據庫編程系列文章,如果能用SQL實現首選還是SQL,這樣處理既直接又快速,不過針對SQL要真的有耐心和信心寫完,調試更是崩潰。由于要寫出文件到硬盤,最后還是選擇MySQL作為數據庫工具,Navicat作為開發工具。

          有兩張表計劃表、市縣表,二者依靠市縣編碼(sxbm)進行等值連接,計劃表內含有各個學校投放在各個市縣的專業代號(zydh),專業名稱(zymc)、招生備注(bz)、學制(xz)、要求的學歷(xl)、計劃數(jh)等字段組成的計劃信息,院校編碼(yxbm)為學校的兩位數編碼,院校代號(yxdh)為院校編碼(yxbm)+市縣編碼(sxbm)組成的四位數編碼,院校代號其實可以區分出學校在哪個市縣的投檔的專業計劃。要求以學校為單位創建HTML頁面,頁面首先要以市縣作為表格分割,然后根據專業代號排序。具體實現過程如下:

          創建計劃表:

          CREATE TABLE `zzjh2019v` (
          `YXDH` varchar(9) COMMENT '學校代號',
          `YXMC` varchar(54) COMMENT '學校名稱',
          `ZYDH` varchar(2) COMMENT '專業代號',
          `ZYMC` varchar(28) COMMENT '專業名稱',
          `XZ` varchar(3) COMMENT '學制',
          `XL` varchar(4) COMMENT '學歷',
          `JH` varchar(6) COMMENT '招生計劃數',
          `BZ` varchar(200) COMMENT '備注',
          `yxbm` char(2) COMMENT '學校編碼',
          `sxbm` char(2) COMMENT '市縣編碼'
          ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_bin ROW_FORMAT = Compact;
          

          創建市縣編碼表:

          CREATE TABLE `sx` (
          `sxbm` char(2) COMMENT '市縣編碼',
          `sxmc` varchar(20) COMMENT '市縣名稱'
          ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_bin ROW_FORMAT = Compact;
          

          糾結了很久這個東西怎么寫,最后采取游標、拼接字符串、字符串聚合,動態SQL,寫文件等一些列操作完成需求,創建的存儲過程如下:

          CREATE DEFINER=`root`@`localhost` PROCEDURE `splitjh`()
          BEGIN
          declare done INT DEFAULT 0;
          declare pyxbm char(2);
          declare psxmc varchar(10);
          declare pyxmc varchar(50);
          declare pjhall int;
          declare pjhrows TEXT;
          declare yxjh cursor
          for
          select yxbm,yxmc,sum(jh) jhall from zzjh2019v a,sx b where a.sxbm=b.sxbm group by yxbm,yxmc order by yxbm;
          declare CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1;
          open yxjh;
          fetch yxjh into pyxbm,pyxmc,pjhall;
          while done !=1 do
          select group_concat(jhrow separator '') into pjhrows from
          (select concat('<tr class="subtitle"><td>',yxdh,'</td><td>',yxmc,'在 <span><font color="red">',b.sxmc,'</font></span> 招生計劃如下</td><td>',sum(jh),'</td><td></td><td></td></tr>',group_concat('<tr class="jhrow"><td>',zydh,'</td><td>',zymc,'(',bz,')</td><td>',jh,'</td><td>',xz,'</td><td>',xl,'</td></tr>' order by zydh separator '')) jhrow
          from zzjh2019v a,sx b where yxbm=pyxbm and a.sxbm=b.sxbm group by yxdh order by yxdh,zydh) jhs;
          set @pfilename = concat('''d:/32/1/1/jh11',pyxbm,'.html''');
          set @sql =concat('select concat(''<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"><link rel="stylesheet" type="text/css" href="zsjh.css" ><title>3+2計劃</title></head><body><h3></h3><table><tr class="subtitle"><th>代號</th><th>專業及名稱備注</th><th>人數</th><th>學制</th><th>學歷</th></tr>'',''',pjhrows,''',''</body></html>'') from dual into outfile ',@pfilename);
          prepare execsql from @sql;
          execute execsql;
          DEALLOCATE PREPARE execsql;
          fetch yxjh into pyxbm,pyxmc,pjhall;
          end while;
          close yxjh;
          END;
          

          首先看效果,執行過程

          call splitjh();
          

          在磁盤形成的HTML文件效果如下圖(數據有一定的敏感性,進行了遮擋處理):

          文件展示頁面

          生成的文件列表如下圖:

          生成的文件列表

          這里一共有87所學校,所以生成了87的文件,添加CSS樣式文件,讓表格呈現如前圖所示。

          技術點

          1)MySQL的游標,以及循環讀取游標的方法,涉及的語句如下:

          declare yxjh cursor
          for
          select yxbm,yxmc,sum(jh) jhall from zzjh2019v a,sx b where a.sxbm=b.sxbm group by yxbm,yxmc order by yxbm;#游標定義
          declare CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1;#游標循環條件,注意此句一定要定義在游標之后,才起作用
          open yxjh;#打開游標
          fetch yxjh into pyxbm,pyxmc,pjhall;#將游標行內容賦值給變量。
          

          2)執行動態SQL,由于MySQL into outfile 后接的文件名不能為變量,所以必須使用動態SQL的方法,涉及的語句如下:

          prepare execsql from @sql;#從一個變量準備一個動態sql,注意execsql不用提前定義
          execute execsql;#執行準備好的語句
          DEALLOCATE PREPARE execsql;#銷毀語句
          

          綜上就是使用MySQL數據庫,并借用MySQL寫文件的方式將數據從數據庫內按照需求導出文件,為何不用navicat導出呢?因為無法達到要求,又是聚合、又是格式,所以只能自己編寫過程通過SQL語句拼接字符串的方式來實現。沒有太多的技術難度,主要是想法和調試難度。后續在此基礎上又開發了以市縣為單位創建HTML文件,各招生學校作為分割的過程。本案例是實際需求催生出來的做法,在遇到這樣的需求前你是先想到SQL還是先想到開發工具呢?從實際效果看使用SQL這種方式更加靈活。這樣的SQL實現的字符串拼接是不是有點極限呢?

          數據庫已經越來越被人們熟知,同時也在許多企業中得到了應用,但是由于市面上沒有統一的圖查詢語言標準,所以有部分開發者對于不同圖數據庫的用法存在著疑問。因此本文作者對市面上主流的幾款圖數據庫進行了一番分析,并以查詢操作為例進行深入介紹。

          文章的開頭我們先來看下什么是圖數據庫,根據維基百科的定義:圖數據庫是使用圖結構進行語義查詢的數據庫,它使用節點、邊和屬性來表示和存儲數據

          雖然和關系型數據庫存儲的結構不同(關系型數據庫為表結構,圖數據庫為圖結構),但不計各自的性能問題,關系型數據庫可以通過遞歸查詢或者組合其他 SQL 語句(Join)完成圖查詢語言查詢節點關系操作。得益于 1987 年 SQL 成為國際標準化組織(ISO)標準,關系型數據庫行業得到了很好的發展。同 60、70 年代的關系型數據庫類似,圖數據庫這個領域的查詢語言目前也沒有統一標準,雖然 19 年 9 月經過國際 SQL 標準委員會投票表決,決定將圖查詢語言(Graph Query Language)納為一種新的數據庫查詢語言,但 GQL 的制定仍需要一段時間。

          鑒于市面上沒有統一的圖查詢語言標準,在本文中我們選取市面上主流的幾款圖查詢語言來分析一波用法,由于篇幅原因本文旨在簡單介紹圖查詢語言和常規用法,更詳細的內容將在進階篇中講述。

          圖查詢語言·介紹

          圖查詢語言 Gremlin

          Gremlin 是 Apache ThinkerPop 框架下的圖遍歷語言。Gremlin 可以是的也可以是命令性的。雖然 Gremlin 是基于 Groovy 的,但具有許多語言變體,允許開發人員以 Java、JavaScript、Python、Scala、Clojure 和 Groovy 等許多現代編程語言原生編寫 Gremlin 查詢

          支持圖數據庫:Janus Graph、InfiniteGraph、Cosmos DB、DataStax Enterprise(5.0+) 、Amazon Neptune

          圖查詢語言 Cypher

          Cypher 是一個描述性的圖形查詢語言,允許不必編寫圖形結構的遍歷代碼對圖形存儲有表現力和效率的查詢,和 SQL 很相似,Cypher 語言的關鍵字不區分大小寫,但是屬性值,標簽,關系類型和變量是區分大小寫的。

          支持圖數據庫: Neo4j、RedisGraph、AgensGraph

          圖查詢語言 nGQL

          nGQL 是一種類 SQL 的聲明型的文本查詢語言,nGQL 同樣是關鍵詞大小寫不敏感的查詢語言,目前支持模式匹配、聚合運算、圖計算,可無嵌入組合語句。

          支持圖數據庫:Nebula Graph

          圖查詢語言·術語篇

          在比較這 3 個圖查詢語言之前,我們先來看看他們各自的術語,如果你翻閱他們的文檔會經常見到下面這些“關鍵字”,在這里我們不講用法,只看這些圖數據庫常用概念在這 3 個圖數據庫文檔中的叫法。

          術語GremlinCyphernGQL點VertexNodeVertex邊EdgeRelationshipEdge點類型LabelLabelTag邊類型labelRelationshipTypeedge type點 IDvidid(n)vid邊 IDeidid?無插入addcreateinsert刪除dropdeletedelete / drop更新屬性setPropertysetupdate

          我們可以看到大體上對點和邊的叫法類似,只不過 Cypher 中直接使用了 Relationship 關系一詞代表邊。其他的術語基本都非常直觀。

          圖查詢語言·實操篇

          上面說了一通術語之類的“干貨”之后,是時候展示真正的技術了——來個具體一點的例子,在具體的例子中我們將會分析 Gremlin、Cypher、nGQL 的用法不同。

          示例圖:The Graphs of Gods

          實操示例使用了 Janus Graph 的示例圖 The Graphs of Gods。該圖結構如下圖所示,描述了羅馬萬神話中諸神關系。

          插入數據

          復制代碼

          # 插入點## nGQLnebula> INSERT VERTEX character(name, age, type) VALUES hash("saturn"):("saturn", 10000, "titan"), hash("jupiter"):("jupiter", 5000, "god");## Gremlingremlin> saturn = g.addV("character").property(T.id, 1).property('name', 'saturn').property('age', 10000).property('type', 'titan').next();==>v[1]gremlin> jupiter = g.addV("character").property(T.id, 2).property('name', 'jupiter').property('age', 5000).property('type', 'god').next();==>v[2]gremlin> prometheus = g.addV("character").property(T.id, 31).property('name',  'prometheus').property('age', 1000).property('type', 'god').next();==>v[31]gremlin> jesus = g.addV("character").property(T.id, 32).property('name',  'jesus').property('age', 5000).property('type', 'god').next();==>v[32]## Cyphercypher> CREATE (src:character {name:"saturn", age: 10000, type:"titan"})cypher> CREATE (dst:character {name:"jupiter", age: 5000, type:"god"})# 插入邊## nGQLnebula> INSERT EDGE father() VALUES hash("jupiter")->hash("saturn"):();## Gremlingremlin> g.addE("father").from(jupiter).to(saturn).property(T.id, 13);==>e[13][2-father->1]## Cyphercypher> CREATE (src)-[rel:father]->(dst)

          在數據插入這塊,我們可以看到 nGQL 使用 INSERT VERTEX 插入點,而 Gremlin 直接使用類函數的 g.addV() 來插入點,Cypher 使用 CREATE 這個 SQL 常見關鍵詞來創建插入的點。在點對應的屬性值方面,nGQL 通過 VALUES 關鍵詞來賦值,Gremlin 則通過操作 .property() 進行對應屬性的賦值,Cypher 更直觀直接在對應的屬性值后面跟上想對應的值。

          在邊插入方面,可以看到和點的使用語法類似,只不過在 Cypher 和 nGQL 中分別使用 -[]-> 和 **-> 來表示關系,而 Gremlin 則用 to() ** 關鍵詞來標識指向關系,在使用這 3 種圖查詢語言的圖數據庫中的邊均為有向邊,下圖左邊為有向邊,右邊為無向邊。

          刪除數據

          復制代碼

          # nGQLnebula> DELETE VERTEX hash("prometheus");# Gremlingremlin> g.V(prometheus).drop();# Cyphercypher> MATCH (n:character {name:"prometheus"}) DETACH DELETE n 

          這里,我們可以看到大家的刪除關鍵詞都是類似的:Delete 和 Drop,不過這里需要注意的是上面術語篇中提過 nGQL 中刪除操作對應單詞有 Delete 和 Drop ,在 nGQL 中 Delete 一般用于點邊,Drop 用于 Schema 刪除,這點和 SQL 的設計思路是一樣的。

          更新數據

          復制代碼

          # nGQLnebula> UPDATE VERTEX hash("jesus") SET character.type = 'titan';# Gremlingremlin> g.V(jesus).property('age', 6000);==>v[32]# Cyphercypher> MATCH (n:character {name:"jesus"}) SET n.type = 'titan';

          可以看到 Cypher 和 nGQL 都使用 SET 關鍵詞來設置點對應的類型值,只不過 nGQL 中多了 UPDATE 關鍵詞來標識操作,Gremlin 的操作和查看點操作類似,只不過增加了變更 property 值操作,這里我們注意到的是,Cypher 中常見的一個關鍵詞便是 MATCH,顧名思義,它是一個查詢關鍵詞,它會去選擇匹配對應條件下的點邊,再進行下一步操作。

          查看數據

          復制代碼

          # nGQLnebula> FETCH PROP ON character hash("saturn");===================================================| character.name | character.age | character.type |===================================================| saturn         | 10000         | titan          |---------------------------------------------------# Gremlingremlin> g.V(saturn).valueMap();==>[name:[saturn],type:[titan],age:[10000]]# Cyphercypher> MATCH (n:character {name:"saturn"}) RETURN properties(n)  ╒════════════════════════════════════════════╕  │"properties(n)"                             │  ╞════════════════════════════════════════════╡  │{"name":"saturn","type":"titan","age":10000}│  └────────────────────────────────────────────┘

          在查看數據這塊,Gremlin 通過調取 valueMap() 獲得對應的屬性值,而 Cypher 正如上面更新數據所說,依舊是 MATCH 關鍵詞來進行對應的匹配查詢再通過 RETURN 返回對應的數值,而 nGQL 則對 saturn 進行 hash 運算得到對應 VID 之后去獲取對應 VID 的屬性值。

          查詢 hercules 的父親

          復制代碼

          # nGQLnebula>  LOOKUP ON character WHERE character.name == 'hercules' | \      -> GO FROM $-.VertexID OVER father YIELD $$.character.name;=====================| $$.character.name |=====================| jupiter           |---------------------# Gremlingremlin> g.V().hasLabel('character').has('name','hercules').out('father').values('name');==>jupiter# Cyphercypher> MATCH (src:character{name:"hercules"})-[:father]->(dst:character) RETURN dst.name      ╒══════════╕      │"dst.name"│      ╞══════════╡      │"jupiter" │      └──────────┘

          查詢父親,其實是一個查詢關系 / 邊的操作,這里不做贅述,上面插入邊的時候簡單介紹了 Gremlin、Cypher、nGQL 這三種圖數據庫是各自用來標識邊的關鍵詞和操作符是什么。

          查詢 hercules 的祖父

          復制代碼

          # nGQLnebula> LOOKUP ON character WHERE character.name == 'hercules' | \     -> GO 2 STEPS FROM $-.VertexID OVER father YIELD $$.character.name;=====================| $$.character.name |=====================| saturn            |---------------------# Gremlingremlin> g.V().hasLabel('character').has('name','hercules').out('father').out('father').values('name');==>saturn# Cyphercypher> MATCH (src:character{name:"hercules"})-[:father*2]->(dst:character) RETURN dst.name      ╒══════════╕      │"dst.name"│      ╞══════════╡      │"saturn"  │      └──────────┘

          查詢祖父,其實是一個查詢對應點的兩跳關系,即:父親的父親,我們可以看到 Gremlin 使用了兩次 out() 來表示為祖父,而 nGQL 這里使用了 (Pipe 管道) 的概念,用于子查詢。在兩跳關系處理上,上面說到 Gremlin 是用了 2 次 out(),而 Cypher、nGQL 則引入了 step 數的概念,分別對應到查詢語句的 GO 2 STEP 和 [:father *2],相對來說 Cypher、nGQL 這樣書寫更優雅。

          查詢年齡大于 100 的人物

          復制代碼

          # nGQLnebula> LOOKUP ON character WHERE character.age > 100 YIELD character.name, character.age;=========================================================| VertexID             | character.name | character.age |=========================================================| 6761447489613431910  | pluto          | 4000          |---------------------------------------------------------| -5860788569139907963 | neptune        | 4500          |---------------------------------------------------------| 4863977009196259577  | jupiter        | 5000          |---------------------------------------------------------| -4316810810681305233 | saturn         | 10000         |---------------------------------------------------------# Gremlingremlin> g.V().hasLabel('character').has('age',gt(100)).values('name');==>saturn==>jupiter==>neptune==>pluto# Cyphercypher> MATCH (src:character) WHERE src.age > 100 RETURN src.name      ╒═══════════╕      │"src.name" │      ╞═══════════╡      │  "saturn" │      ├───────────┤      │ "jupiter" │      ├───────────┤      │ "neptune" │      │───────────│      │  "pluto"  │      └───────────┘

          這個是一個典型的查詢語句,找尋符合特定條件的點并返回結果,在 Cypher 和 nGQL 中用 WHRER 進行條件判斷,而 Gremlin 延續了它的“編程風”用 gt(100) 表示年大于齡 100 的這個篩選條件,延伸下 Gremlin 中 eq() 則表示等于這個查詢條件。

          從一起居住的人物中排除 pluto 本人

          復制代碼

          # nGQLnebula>  GO FROM hash("pluto") OVER lives YIELD lives._dst AS place | GO FROM $-.place OVER lives REVERSELY WHERE $$.character.name != "pluto" YIELD $$.character.name AS cohabitants;===============| cohabitants |===============| cerberus    |---------------# Gremlingremlin> g.V(pluto).out('lives').in('lives').where(is(neq(pluto))).values('name');==>cerberus# Cyphercypher> MATCH (src:character{name:"pluto"})-[:lives]->()<-[:lives]-(dst:character) RETURN dst.name      ╒══════════╕      │"dst.name"│      ╞══════════╡      │"cerberus"│      └──────────┘

          這是一個沿指定點 Pluto 反向查詢指定邊(居?。┑牟僮鳎诜聪虿樵冎?,Gremlin 使用了 in 來表示反向關系,而 Cypher 則更直觀的將指向箭頭反向變成 <- 來表示反向關系,nGQL 則用關鍵詞 REVERSELY 來標識反向關系。

          Pluto 的兄弟們居住在哪

          復制代碼

          # which brother lives in which place?## nGQLnebula> GO FROM hash("pluto") OVER brother YIELD brother._dst AS god | \GO FROM $-.god OVER lives YIELD $^.character.name AS Brother, $$.location.name AS Habitations;=========================| Brother | Habitations |=========================| jupiter | sky         |-------------------------| neptune | sea         |-------------------------## Gremlingremlin> g.V(pluto).out('brother').as('god').out('lives').as('place').select('god','place').by('name');==>[god:jupiter, place:sky]==>[god:neptune, place:sea]## Cyphercypher> MATCH (src:Character{name:"pluto"})-[:brother]->(bro:Character)-[:lives]->(dst)RETURN bro.name, dst.name      ╒═════════════════════════╕      │"bro.name"    │"dst.name"│      ╞═════════════════════════╡      │ "jupiter"    │  "sky"   │      ├─────────────────────────┤      │ "neptune"    │ "sea"    │      └─────────────────────────┘

          這是一個通過查詢指定點 Pluto 查詢指定邊 brother 后再查詢指定邊 live 的查詢,相對來說不是很復雜,這里就不做解釋說明了。

          最后,本文只是對 Gremlin、Cypher、nGQL 等 3 個圖查詢語言進行了簡單的介紹,更復雜的語法將在本系列的后續文章中繼續,歡迎在論壇留言交流。


          主站蜘蛛池模板: 国产一区二区三区四| 视频一区在线播放| 91视频国产一区| 性色AV一区二区三区| 亚洲AV无码第一区二区三区| 亚洲一区二区三区香蕉| 无码国产精品一区二区免费模式 | 亚洲熟女少妇一区二区| 色狠狠一区二区三区香蕉蜜桃| 日本道免费精品一区二区| 精品一区二区三区四区| 亚洲乱码一区二区三区国产精品| 韩国一区二区三区| 国产在线视频一区| 国产成人亚洲综合一区| 精品在线视频一区| 无码人妻久久久一区二区三区| 亚洲一区AV无码少妇电影| 一区二区视频免费观看| 国产一区二区福利| 精品久久综合一区二区| 日本亚洲成高清一区二区三区| 亚洲欧美国产国产一区二区三区| 四虎永久在线精品免费一区二区| 国产亚洲一区二区三区在线观看 | 精品人体无码一区二区三区| 久久久无码精品国产一区| 天堂成人一区二区三区| 国产AV午夜精品一区二区三| 理论亚洲区美一区二区三区| 国产午夜精品一区二区三区小说| 中文字幕无线码一区二区| 国产精品主播一区二区| 天堂Av无码Av一区二区三区| 中文字幕一区视频一线| 成人免费一区二区无码视频| 久久精品一区二区三区不卡| 国产在线一区二区三区av| 亚洲国产精品一区二区久久| 亚洲高清成人一区二区三区| 亚洲欧洲无码一区二区三区|