วันนี้เรายินดีประกาศ General Availability release ของ RedisGraph 2.8 บล็อกโพสต์นี้รายละเอียด major new features ที่พร้อมใช้งานแล้ว
เกี่ยวกับ RedisGraph
RedisGraph เป็น high-performance, memory-first graph data structure สำหรับ Redis RedisGraph รองรับ graph multi-tenancy (สามารถ hold many graphs simultaneously ได้) และสามารถ serve multiple clients accessing the graphs simultaneously ได้ ตอนนี้มีให้เป็นส่วนหนึ่งของ Redis Stack ด้วย
Major new features in RedisGraph 2.8 (ฟีเจอร์ใหม่หลักใน RedisGraph 2.8)
- Richer graph model (โมเดลกราฟที่อุดมสมบูรณ์กว่า)
- Multi-labeled nodes (โหนดหลายฉลาก)
- Enhanced querying capabilities (ความสามารถในการ query ที่เพิ่มขึ้น)
- Enhanced full-text search (การค้นหาข้อความเต็มที่เพิ่มประสิทธิภาพ)
- Supporting more Cypher constructs, functions, และ operators
- Performance improvements (การปรับปรุงประสิทธิภาพ)
- Indexes over relationship properties (ดัชนีเหนือคุณสมบัติความสัมพันธ์)
- Delta Matrices
- Controllable node creation buffer (บัฟเฟอร์การสร้างโหนดที่ควบคุมได้)
- Benchmarks
https://redis.com/blog/redisgraph-2-8-is-generally-available/(opens in a new tab)
Richer graph model (โมเดลกราฟที่อุดมสมบูรณ์กว่า)
Multi-labeled nodes (โหนดหลายฉลาก)
หลาย definitions ของ Labelled Property Graph (LPG) data model (เช่น The Property Graph Database Model – Angles, 2018, และ ISO/IEC JTC 1/SC 32 – GQL draft) ระบุว่าโหนดสามารถมี multiple labels (หลายฉลาก) ได้ จนถึง v2.8 RedisGraph รองรับ only a single label ตั้งแต่ตอนนี้ เราสามารถ add multiple labels ให้แต่ละโหนดได้โดยไม่มี performance degradation (การลดประสิทธิภาพ) หรือ significant memory increase (การเพิ่มหน่วยความจำอย่างมีนัยสำคัญ)
เพื่อสร้างโหนดด้วย multiple labels คุณแค่ list ทุก labels แยกด้วย colon:
GRAPH.QUERY g "CREATE (e:Employee:BoardMember {Name: 'Vincent Chan', Title: 'Web marketing lead'}) return e"
เพื่อ match โหนดด้วย multiple labels (AND condition) คุณควรใช้ colon notation เดียวกัน:
GRAPH.QUERY g "MATCH (e:Employee:BoardMember) return e"
Enhanced Querying Capabilities (ความสามารถในการ Query ที่เพิ่มขึ้น)
Enhanced full-text search (การค้นหาข้อความเต็มที่เพิ่มประสิทธิภาพ)
RedisGraph มาพร้อมกับ RedisSearch embedded และถูกใช้ประโยชน์สำหรับ secondary indexing แต่ยังสามารถใช้สำหรับ advanced indexing และ searching ได้ เช่น – การหา nodes based on geographical proximity (ความใกล้ชิดทางภูมิศาสตร์) ไปยังจุดบนโลกที่กำหนด หรือ scoring related items higher
Version 2.8 เพิ่ม language และ stopwords configuration options language กำหนดภาษาที่ใช้สำหรับ stemming text – ซึ่งคือการเพิ่ม base form ของคำเข้า index นี่อนุญาตให้ query สำหรับ "going" ยัง return results สำหรับ "go" และ "gone" ได้ stopwords เป็นคำที่พบบ่อยมาก (เช่น "is, the, an, and…") ที่ไม่เพิ่ม information ให้ search มากแตกใช้พื้นที่มากใน index คำเหล่านี้ไม่ถูก indexed และ ignored เมื่อ search query term ที่มี stopword อยู่ เช่น "in Paris" จะถูกมองเห็นว่า "Paris" เท่านั้น
เพื่อสร้าง full-text index บน title property ของ movies โดยใช้ German language และ custom stopwords ของทุก nodes ที่มี label Movie:
GRAPH.QUERY DEMO_GRAPH "CALL db.idx.fulltext.createNodeIndex({ label: 'Movie', language: 'German', stopwords: ['a', 'ab'] }, 'title')"
RediSearch ให้ 3 additional field configuration options เพิ่มเติม:
- weight – ความสำคัญของข้อความใน field
- nostem – ข้าม stemming เมื่อ indexing text
- phonetic – เปิดใช้ phonetic search บน text
เพื่อสร้าง full-text index บน title property พร้อม phonetic search ของทุก nodes ที่มี label Movie:
GRAPH.QUERY DEMO_GRAPH "CALL db.idx.fulltext.createNodeIndex('Movie', {field: 'title', phonetic: 'dm:en'})"
Supporting more Cypher construct, functions, and operators (รองรับ Cypher constructs, functions, และ operators มากขึ้น)
RedisGraph 2.8 extended Cypher support coverage:
- Pattern comprehensions
- Add support สำหรับ
allShortestPaths
function - Cypher functions:
keys, reduce, replace, none,
และsingle
- Copying of node attribute-sets ใน
SET
clauses - Filtering by node label ใน
WHERE
clauses - Cypher operators:
XOR
และ^
Pattern comprehensions (Pattern comprehensions)
Pattern comprehension เป็น syntactic construct ที่มีใน Cypher ในขณะที่ list comprehensions อนุญาตให้เราสร้าง list based on existing lists pattern comprehension เป็นวิธี populate list ด้วย results ของ matchings ของ pattern มันจะ match specified pattern เหมือนใน standard
MATCHclause ด้วย predicates เหมือนใน standard
WHEREclause แต่ yield specified projection
ตัวอย่าง query ต่อไปนี้จะ return list ที่มี all grant types ที่ male employees ได้รับ โดยที่ grant amount มากกว่า $1000
GRAPH.QUERY g "CREATE (e:Employee {gender:'Male'})-[:granted]->(g:Grant {type: 'Research', amount: 2000})"
GRAPH.QUERY g "MATCH (e:Employee {gender:'Male'}) RETURN [(e)-[:granted]->(g:Grant) WHERE g.amount > 1000 | g.type] AS grantTypes"
Add support for allShortestPaths function
allShortestPathsfunction คืนค่า all the shortest paths ระหว่าง pair of entities ที่ match all criteria ทั้งสอง entities ต้อง bound ใน earlier
WITH-demarcated scope
GRAPH.QUERY DEMO_GRAPH "MATCH (c:Actor {name: 'Charlie Sheen'}), (k:Actor {name: 'Kevin Bacon'}) WITH c, k MATCH p = allShortestPaths((c)-[:PLAYED_WITH*]->(k)) RETURN nodes(p) as actors"
Query นี้จะ produce all paths ของ minimum length connecting actor node ที่ represent Charlie Sheen ไปยัง Kevin Bacon มี several 2-hop paths ระหว่างสอง actors และทั้งหมดจะถูก return การคำนวณ paths จึง terminate เพราะเราไม่สนใจ paths ที่ยาวกว่า 2
Minimal length (ต้องเป็น 1) และ maximal length (ต้องน้อยที่สุด 1) สำหรับ search อาจ specified ได้ Zero or more relationship types อาจ specified ได้ (เช่น
[:R|Q*1..3]) No property filters อาจ introduced ใน pattern
Add support for keys Cypher function
keysfunction ยอมรับ node, a relationship, หรือ a map เป็น input และคืนค่า array ของ all the keys ที่ input contains
MATCH (a) RETURN keys(a)
MATCH ()-[e]->() RETURN keys(e)
RETURN keys({a:1, b:2})
Add support for reduce Cypher function
reducefunction ยอมรับ starting value และ a list มันจะ update value โดย evaluate expression ต่อแต่ละ element ของ list
GRAPH.QUERY g "RETURN reduce(sum = 0, n IN range(1,10) | sum + n)"
Output ของ function นี้จะเป็น 55 – ผลรวมของ integers ระหว่าง 1 และ 10
GRAPH.QUERY g "RETURN reduce(arr = [], n IN range(1,10) | arr + [n*n])"
Output ของ function นี้จะเป็น array ที่มี squares ของ integers ระหว่าง 1 และ 10
Add support for replacing Cypher string function (ฟังก์ชันสตริง Cypher แทนที่)
Replaces all the occurrences ของ given substring ด้วยอีกอันหนึ่ง Function รับ 3 parameters: original string, occurrences to replace, และ what to replace them with
GRAPH.QUERY g "RETURN replace('abc*efg', '*', 'd')"Return value จะเป็น 'abcdefg'
Function นี้ยังสามารถ delete substrings ได้โดยแทนที่ด้วย empty string ('')
Add support for none และ single Cypher function
Given a list, none คืนค่า true หาก predicate ไม่ hold สำหรับ any element ในขณะที่ single คืนค่า true หาก given predicate hold สำหรับ only one element
GRAPH.QUERY g "RETURN none(x IN range(1,10) WHERE x>10)" GRAPH.QUERY g "RETURN single(x IN range(1,10) WHERE x>9)"
Functions เหล่านี้ similar to all and any functions
One possible use case คือ path filtering:
graph.query DEMO_GRAPH "MATCH p = (a {name:'Johnny Depp'})-[*2..5]->(b {name:'Kevin Bacon'}) WHERE none(n IN nodes(p) WHERE n.year > 1970) RETURN p"
Query นี้จะ return all paths of length 2 to 5 จาก Johnny Depp ไป Kevin Bacon ซึ่ง include no actor born after 1970
Add support for copying of node attribute sets in SET
clauses
SETclause สามารถใช้ replace หรือ append all the property values ของ one node ด้วย property values ของ another node
Query ต่อไปนี้จะ match two entities และ replace all a's properties ด้วย b's properties:
GRAPH.QUERY g "MATCH (a {v: 1}), (b {v: 2}) SET a = b"
Query ต่อไปนี้จะ match two entities และ add (หรือ replace the values) ของ a's properties ด้วย b's properties:
GRAPH.QUERY g "MATCH (a {v: 1}), (b {v: 2}) SET a += b"
เรายังสามารถ change a relationship's type โดยไม่เปลี่ยน properties:
GRAPH.QUERY g "MATCH (a)-[b]->(c) WHERE ID(b)=0 CREATE (a)-[d:bar]->(c) SET d=b DELETE b RETURN d"
Add support for filtering by node label in WHERE clause
ตอนนี้สามารถ filter by node label หรือ relationship type ใน WHERE clause ได้:
GRAPH.QUERY g "MATCH (a) WHERE a:L RETURN a" GRAPH.QUERY g "MATCH (a)-[b]-(c) WHERE b:L RETURN b"
Add support for Cypher operators XOR และ ^
GRAPH.QUERY g "RETURN true XOR true" GRAPH.QUERY g "RETURN 2 ^ 3"
Results คือ
falseและ
8ตามลำดับ
Performance Improvements (การปรับปรุงประสิทธิภาพ)
Indexes over relationship properties (ดัชนีเหนือคุณสมบัติความสัมพันธ์)
สำหรับ nodes เราสามารถ introduce index ได้โดยออกคำสั่ง:
GRAPH.QUERY g "CREATE INDEX FOR (n:GRANTS) ON (n.GrantedBy)"
ตอนนี้สามารถ introduce indexes สำหรับ relationships ได้เช่นกัน:
GRAPH.QUERY g "CREATE INDEX FOR ()-[r:R]-() ON (r.prop)"
พิจารณา query ต่อไปนี้:
GRAPH.QUERY g "MATCH (a)-[r:R {prop:5}]-(b) return *"
มาสังเกต execution plan ก่อนสร้าง index:
redis:6379> GRAPH.EXPLAIN g "MATCH (a)-[r:R {prop:5}]-(b) return *"
1) "Results" 2) " Project" 3) " Filter" 4) " Conditional Traverse | (a)-[r:R]->(b)" 5) " All Node Scan | (a)" |
And this is the execution plan for the same query after creating an index:
redis:6379> GRAPH.EXPLAIN g "MATCH (a)-[r:R {prop:5}]-(b) return *"
1) "Results" 2) " Project" 3) " Edge By Index Scan | [r:R]" |
Delta Matrices
ตั้งแต่ version 2.8 graph nodes และ relationships additions และ deletions เร็วกว่ามาก เพราะพวกเขาถูก updated first ใน small delta matrices Main matrices จึง bulk-updated แทน
ใน RedisGraph graphs ถูก represented ด้วย adjacency matrices ทุก node label และทุก relationship type ใน graph มี matrix ของตัวเอง ก่อนหน้านี้ ทุกครั้งที่ new node ถูกเพิ่มเข้า graph ทุก matrices ต้อง resized และ database 越大 (bigger) 越花时间 (the more time this took)

ตั้งแต่ v2.8 เวลาที่ใช้ insert new nodes และ relationships 小得多 (substantially smaller) และไม่ depend on (ขึ้นอยู่กับ) the size of the graph อีกต่อไป Optimization นี้ achieved (บรรลุ) โดย introducing two delta matrices สำหรับ every matrix ใน graph: one for node additions (D+) และ one for node deletions (D-) Node additions และ deletions สะท้อนใน delta matrix ที่เหมาะสม และ once a delta matrix reaches a threshold of 10000 nodes (configurable via
DELTA_MAX_PENDING_CHANGESconfiguration parameter) มันจะ synchronized กับ main matrix ใน single bulk operation, emptied, และ same cycle 可以再次开始 (can start again)
Controllable node creation buffer (บัฟเฟอร์การสร้างโหนดที่ควบคุมได้)
Load-time configuration parameter ใหม่ NODE_CREATION_BUFFER ควบคุม amount of memory reserved in matrices สำหรับ future node creations ตัวอย่าง เมื่อ set to 16,384 matrices จะมี extra space สำหรับ 16384 nodes upon creation Whenever the extra space is depleted (หมด) matrices' size จะ increase by 16384
Reducing this value จะ reduce memory consumption แต่ cause performance degradation เนื่องจาก increased frequency of matrix reallocations Conversely (ในทางกลับกัน) increasing it might improve performance for write-heavy workloads แต่จะ increase memory consumption
If the passed argument was not a power of 2 มันจะ rounded to the next-greatest power of 2 เพื่อ improve memory alignment
Benchmarks
เรายังเพิ่ม many other performance enhancements นอกจาก delta matrices เราสาธิต improvements เหล่านี้ด้านล่างโดยใช้ LDBC SNB benchmark
The LDBC SNB (Linked Data Benchmark Council – Social Network Benchmarks) เป็น industry-standard benchmark สำหรับเปรียบเทียบ graph database real-world reads และ writes workloads
Overall data load เร็วกว่ามากใน RedisGraph 2.8:
- LDBC scale factor 1:
RedisGraph 2.8 เร็วกว่า RedisGraph 2.4 1.92 เท่า - LDBC scale factor 10:
RedisGraph 2.8 เร็วกว่า RedisGraph 2.4 2.00 เท่า

LDBC queries (both read and write) executed เร็วกว่ามากใน RedisGraph 2.8:
- Read queries:
RedisGraph 2.8 เร็วกว่า RedisGraph 2.4 2.32 เท่า - Write queries:
RedisGraph 2.8 เร็วกว่า RedisGraph 2.4 1.09 เท่า

Restoring and syncing data (RDB and AOF) เร็วกว่ามากเช่นกัน (up to several orders of magnitude faster ในบาง situations)
RedisGraph เป็นส่วนหนึ่งของ Redis Stack
RedisGraph ตอนนี้เป็นส่วนหนึ่งของ Redis Stack คุณสามารถ download latest Redis Stack Server binaries สำหรับ macOS, Ubuntu, หรือ Redhat หรือ install ด้วย Docker, Homebrew, หรือ Linux
Experience RedisGraph ใช้ RedisInsight
RedisInsight เป็น visual tool สำหรับ developers ที่ให้ excellent way เพื่อ explore data from RedisTimes ระหว่าง development ใช้ Redis หรือ Redis Stack

คุณสามารถ execute graph queries และ observe results โดยตรงจาก graphical user interface RedisInsight ตอนนี้สามารถ visualize RedisGraph query results ได้

เพิ่มเติม RedisInsight มี quick guides และ tutorials สำหรับเรียนรู้ RedisGraph แบบ interactive
Learn more on RedisGraph on redis.io and developer.redis.com.