සුදුසු මාර්ග සෙවීමේ ගැටලුව විසඳීම සඳහා JanusGraph ප්‍රස්ථාර DBMS හි අදාළත්වය පරීක්ෂා කරන අත්හදා බැලීමක්

සුදුසු මාර්ග සෙවීමේ ගැටලුව විසඳීම සඳහා JanusGraph ප්‍රස්ථාර DBMS හි අදාළත්වය පරීක්ෂා කරන අත්හදා බැලීමක්

ආයුබෝවන් සියල්ලටම. අපි නොබැඳි ගමනාගමන විශ්ලේෂණය සඳහා නිෂ්පාදනයක් සංවර්ධනය කරමින් සිටිමු. ව්‍යාපෘතියට කලාප හරහා නරඹන්නන්ගේ මාර්ග සංඛ්‍යානමය විශ්ලේෂණයට සම්බන්ධ කාර්යයක් ඇත.

මෙම කාර්යයේ කොටසක් ලෙස, පරිශීලකයින්ට පහත ආකාරයේ පද්ධති විමසුම් ඇසිය හැක:

  • "A" ප්‍රදේශයේ සිට "B" ප්‍රදේශයට පැමිණි අමුත්තන් සංඛ්‍යාව කොපමණද;
  • "A" ප්‍රදේශයේ සිට "B" ප්‍රදේශයට "C" ප්‍රදේශය හරහා සහ පසුව "D" ප්‍රදේශය හරහා පැමිණි අමුත්තන් සංඛ්‍යාව කොපමණද;
  • "A" ප්‍රදේශයේ සිට "B" ප්‍රදේශයට ගමන් කිරීමට යම් ආකාරයක ආගන්තුකයෙකුට කොපමණ කාලයක් ගත විය.

සහ සමාන විශ්ලේෂණ විමසුම් ගණනාවක්.

ප්‍රදේශ හරහා පැමිණෙන අමුත්තන්ගේ සංචලනය අධ්‍යක්ෂණය කරන ලද ප්‍රස්ථාරයකි. අන්තර්ජාලය කියවීමෙන් පසු, විශ්ලේෂණ වාර්තා සඳහා ප්‍රස්ථාර DBMS ද භාවිතා කරන බව මම සොයා ගතිමි. ප්‍රස්ථාර DBMS එවැනි විමසුම් සමඟ කටයුතු කරන්නේ කෙසේදැයි බැලීමට මට ආශාවක් තිබුණි (ටීඑල්; ඩීආර්; දුර්වල ලෙස).

මම DBMS භාවිතා කිරීමට තෝරා ගත්තෙමි JanusGraph, (මගේ මතය අනුව) එයට යහපත් මෙහෙයුම් ලක්ෂණ සැපයිය යුතු පරිණත තාක්‍ෂණ තොගයක් මත රඳා පවතින, ප්‍රස්ථාර විවෘත මූලාශ්‍ර DBMS හි කැපී පෙනෙන නියෝජිතයෙකු ලෙස:

  • BerkeleyDB ගබඩා පසුබිම, Apache Cassandra, Scylla;
  • සංකීර්ණ දර්ශක Lucene, Elasticsearch, Solr හි ගබඩා කළ හැක.

JanusGraph හි කතුවරුන් ලියන්නේ එය OLTP සහ OLAP යන දෙකටම සුදුසු බවයි.

මම BerkeleyDB, Apache Cassandra, Scylla සහ ES සමඟ වැඩ කර ඇති අතර, මෙම නිෂ්පාදන බොහෝ විට අපගේ පද්ධතිවල භාවිතා වේ, එබැවින් මෙම ප්‍රස්ථාරය DBMS පරීක්ෂා කිරීම ගැන මම සුභවාදීව සිටියෙමි. RocksDB ට වඩා BerkeleyDB තෝරා ගැනීම මට අමුතු දෙයක් විය, නමුත් එය බොහෝ විට ගනුදෙනු අවශ්‍යතා නිසා විය හැකිය. ඕනෑම අවස්ථාවක, පරිමාණය කළ හැකි, නිෂ්පාදන භාවිතය සඳහා, Cassandra හෝ Scylla මත පසුබිමක් භාවිතා කිරීමට යෝජනා කෙරේ.

මම Neo4j සලකා බැලුවේ නැත, මන්ද පොකුරු කිරීමට වාණිජ අනුවාදයක් අවශ්‍ය වේ, එනම් නිෂ්පාදනය විවෘත මූලාශ්‍රයක් නොවේ.

ප්‍රස්ථාර DBMS පවසන්නේ: "එය ප්‍රස්ථාරයක් ලෙස පෙනේ නම්, එය ප්‍රස්ථාරයක් ලෙස සලකන්න!" - අලංකාරය!

පළමුව, මම ප්‍රස්ථාරයක් ඇන්දෙමි, එය හරියටම ප්‍රස්ථාර DBMS හි කැනන අනුව සාදන ලදී:

සුදුසු මාර්ග සෙවීමේ ගැටලුව විසඳීම සඳහා JanusGraph ප්‍රස්ථාර DBMS හි අදාළත්වය පරීක්ෂා කරන අත්හදා බැලීමක්

සාරයක් තියෙනවා Zone, ප්රදේශය සඳහා වගකිව යුතු ය. නම් ZoneStep මෙයට අයත් වේ Zone, එවිට ඔහු එය යොමු කරයි. සාරය මත Area, ZoneTrack, Person අවධානය යොමු නොකරන්න, ඔවුන් වසමට අයත් වන අතර පරීක්ෂණයේ කොටසක් ලෙස නොසැලකේ. සමස්තයක් වශයෙන්, එවැනි ප්‍රස්ථාර ව්‍යුහයක් සඳහා දාම සෙවුම් විමසුමක් පෙනෙන්නේ:

g.V().hasLabel('Zone').has('id',0).in_()
       .repeat(__.out()).until(__.out().hasLabel('Zone').has('id',19)).count().next()

රුසියානු භාෂාවෙන් ඇති දෙය මෙවැනි දෙයකි: ID=0 සහිත කලාපයක් සොයා ගන්න, එයට දාරයක් යන සියලුම සිරස් ගන්න (ZoneStep), කලාපයට දාරයක් ඇති එම ZoneSteps ඔබ සොයා ගන්නා තෙක් ආපසු නොයන්න. ID=19, එවැනි දාම ගණන ගණන් කරන්න.

ප්‍රස්ථාර මත සෙවීමේ සියලු සංකීර්ණතා මම දන්නා බව මවාපාන්නේ නැත, නමුත් මෙම විමසුම මෙම පොත මත පදනම්ව ජනනය කරන ලදී (https://kelvinlawrence.net/book/Gremlin-Graph-Guide.html).

මම BerkeleyDB පසුපෙළ භාවිතා කරමින්, ලකුණු 50 සිට 3 දක්වා දිගින් යුත් ධාවන පථ 20 ක් JanusGraph ප්‍රස්තාර දත්ත ගබඩාවකට පටවා, අනුව දර්ශක නිර්මාණය කළෙමි. නායකත්වය.

පයිතන් බාගැනීමේ පිටපත:


from random import random
from time import time

from init import g, graph

if __name__ == '__main__':

    points = []
    max_zones = 19
    zcache = dict()
    for i in range(0, max_zones + 1):
        zcache[i] = g.addV('Zone').property('id', i).next()

    startZ = zcache[0]
    endZ = zcache[max_zones]

    for i in range(0, 10000):

        if not i % 100:
            print(i)

        start = g.addV('ZoneStep').property('time', int(time())).next()
        g.V(start).addE('belongs').to(startZ).iterate()

        while True:
            pt = g.addV('ZoneStep').property('time', int(time())).next()
            end_chain = random()
            if end_chain < 0.3:
                g.V(pt).addE('belongs').to(endZ).iterate()
                g.V(start).addE('goes').to(pt).iterate()
                break
            else:
                zone_id = int(random() * max_zones)
                g.V(pt).addE('belongs').to(zcache[zone_id]).iterate()
                g.V(start).addE('goes').to(pt).iterate()

            start = pt

    count = g.V().count().next()
    print(count)

අපි SSD එකක cores 4ක් සහ 16 GB RAM එකක් තියෙන VM එකක් පාවිච්චි කළා. JanusGraph මෙම විධානය භාවිතයෙන් යොදවා ඇත:

docker run --name janusgraph -p8182:8182 janusgraph/janusgraph:latest

මෙම අවස්ථාවේදී, නිවැරදි ගැලපීම් සෙවීම් සඳහා භාවිතා කරන දත්ත සහ දර්ශක BerkeleyDB හි ගබඩා කර ඇත. කලින් ලබා දුන් ඉල්ලීම ක්‍රියාත්මක කිරීමෙන් මට තත්පර දස කිහිපයකට සමාන කාලයක් ලැබුණි.

ඉහත ස්ක්‍රිප්ට් 4 සමාන්තරව ක්‍රියාත්මක කිරීමෙන්, ඩොකර් ලොග තුළ ප්‍රීතිමත් ජාවා ස්ටැක්ට්‍රේස් (සහ අපි කවුරුත් ජාවා ස්ටැක්ට්‍රේස් කියවීමට ප්‍රිය කරමු) සමඟින් DBMS වට්ටක්කා ගෙඩියක් බවට පත් කිරීමට මට හැකි විය.

මදක් සිතා බැලීමෙන් පසු, මම ප්‍රස්ථාර සටහන පහත පරිදි සරල කිරීමට තීරණය කළෙමි:

සුදුසු මාර්ග සෙවීමේ ගැටලුව විසඳීම සඳහා JanusGraph ප්‍රස්ථාර DBMS හි අදාළත්වය පරීක්ෂා කරන අත්හදා බැලීමක්

ආයතන ගුණාංග අනුව සෙවීම දාරවලින් සෙවීමට වඩා වේගවත් බව තීරණය කිරීම. එහි ප්‍රතිඵලයක් වශයෙන්, මගේ ඉල්ලීම පහත පරිදි විය.

g.V().hasLabel('ZoneStep').has('id',0).repeat(__.out().simplePath()).until(__.hasLabel('ZoneStep').has('id',19)).count().next()

රුසියානු භාෂාවෙන් ඇත්තේ මෙවැනි දෙයකි: ID=0 සමඟ ZoneStep සොයා ගන්න, ID=19 සමඟ ZoneStep සොයා ගන්නා තෙක් ආපසු නොයා ස්ටම්ප් කරන්න, එවැනි දාම ගණන ගණන් කරන්න.

මම ගුණාංග වලට සීමා වෙමින් අනවශ්‍ය සම්බන්ධතා ඇති නොකිරීමට ඉහත ලබා දී ඇති පූරණ ස්ක්‍රිප්ට් ද සරල කළෙමි.

ඉල්ලීම සම්පූර්ණ කිරීමට තවමත් තත්පර කිහිපයක් ගත විය, එය අපගේ කාර්යය සඳහා සම්පූර්ණයෙන්ම පිළිගත නොහැකි විය, මන්ද එය කිසිදු ආකාරයක AdHoc ඉල්ලීම් සඳහා කිසිසේත්ම සුදුසු නොවේ.

මම වේගවත්ම Cassandra ක්‍රියාත්මක කිරීම ලෙස Scylla භාවිතා කරමින් JanusGraph යෙදවීමට උත්සාහ කළ නමුත්, මෙය ද කිසිදු සැලකිය යුතු කාර්ය සාධන වෙනසක් ඇති කළේ නැත.

එබැවින් "එය ප්‍රස්ථාරයක් මෙන් පෙනේ" යන කාරණය තිබියදීත්, එය ඉක්මනින් සැකසීමට ප්‍රස්ථාර DBMS ලබා ගැනීමට මට නොහැකි විය. මම සම්පූර්ණයෙන්ම උපකල්පනය කරන්නේ මා නොදන්නා දෙයක් ඇති බවත් JanusGraph හට තත්පරයකින් කොටසකින් මෙම සෙවීම සිදු කළ හැකි බවත්, කෙසේ වෙතත්, මට එය කිරීමට නොහැකි විය.

ගැටලුව තවමත් විසඳිය යුතු බැවින්, මම වගු වල JOINs සහ Pivots ගැන සිතීමට පටන් ගතිමි, එය අලංකාරය අනුව ශුභවාදී හැඟීමක් ඇති නොකළ නමුත් ප්‍රායෝගිකව සම්පූර්ණයෙන්ම ක්‍රියාත්මක කළ හැකි විකල්පයක් විය හැකිය.

අපගේ ව්‍යාපෘතිය දැනටමත් Apache ClickHouse භාවිතා කරයි, එබැවින් මම මෙම විශ්ලේෂණාත්මක DBMS පිළිබඳ මගේ පර්යේෂණ පරීක්ෂා කිරීමට තීරණය කළෙමි.

සරල වට්ටෝරුවක් භාවිතා කරමින් ClickHouse යොදවා ඇත:

sudo docker run -d --name clickhouse_1 
     --ulimit nofile=262144:262144 
     -v /opt/clickhouse/log:/var/log/clickhouse-server 
     -v /opt/clickhouse/data:/var/lib/clickhouse 
     yandex/clickhouse-server

මම එහි දත්ත සමුදායක් සහ වගුවක් නිර්මාණය කළෙමි:

CREATE TABLE 
db.steps (`area` Int64, `when` DateTime64(1, 'Europe/Moscow') DEFAULT now64(), `zone` Int64, `person` Int64) 
ENGINE = MergeTree() ORDER BY (area, zone, person) SETTINGS index_granularity = 8192

මම එය පහත ස්ක්‍රිප්ට් භාවිතයෙන් දත්ත වලින් පුරවා ගත්තෙමි:

from time import time

from clickhouse_driver import Client
from random import random

client = Client('vm-12c2c34c-df68-4a98-b1e5-a4d1cef1acff.domain',
                database='db',
                password='secret')

max = 20

for r in range(0, 100000):

    if r % 1000 == 0:
        print("CNT: {}, TS: {}".format(r, time()))

    data = [{
            'area': 0,
            'zone': 0,
            'person': r
        }]

    while True:
        if random() < 0.3:
            break

        data.append({
                'area': 0,
                'zone': int(random() * (max - 2)) + 1,
                'person': r
            })

    data.append({
            'area': 0,
            'zone': max - 1,
            'person': r
        })

    client.execute(
        'INSERT INTO steps (area, zone, person) VALUES',
        data
    )

ඇතුළු කිරීම් කණ්ඩායම් වශයෙන් පැමිණෙන බැවින්, පිරවීම JanusGraph සඳහා වඩා වේගවත් විය.

JOIN භාවිතයෙන් විමසුම් දෙකක් සාදන ලදී. A ලක්ෂ්‍යයේ සිට B ලක්ෂයට ගමන් කිරීමට:

SELECT s1.person AS person,
       s1.zone,
       s1.when,
       s2.zone,
       s2.when
FROM
  (SELECT *
   FROM steps
   WHERE (area = 0)
     AND (zone = 0)) AS s1 ANY INNER JOIN
  (SELECT *
   FROM steps AS s2
   WHERE (area = 0)
     AND (zone = 19)) AS s2 USING person
WHERE s1.when <= s2.when

කරුණු 3 ක් හරහා යාමට:

SELECT s3.person,
       s1z,
       s1w,
       s2z,
       s2w,
       s3.zone,
       s3.when
FROM
  (SELECT s1.person AS person,
          s1.zone AS s1z,
          s1.when AS s1w,
          s2.zone AS s2z,
          s2.when AS s2w
   FROM
     (SELECT *
      FROM steps
      WHERE (area = 0)
        AND (zone = 0)) AS s1 ANY INNER JOIN
     (SELECT *
      FROM steps AS s2
      WHERE (area = 0)
        AND (zone = 3)) AS s2 USING person
   WHERE s1.when <= s2.when) p ANY INNER JOIN
  (SELECT *
   FROM steps
   WHERE (area = 0)
     AND (zone = 19)) AS s3 USING person
WHERE p.s2w <= s3.when

ඉල්ලීම්, ඇත්ත වශයෙන්ම, තරමක් බියජනක ලෙස පෙනේ; සැබෑ භාවිතය සඳහා, ඔබ මෘදුකාංග උත්පාදක පටි නිර්මාණය කළ යුතුය. කෙසේ වෙතත්, ඔවුන් වැඩ කරන අතර ඔවුන් ඉක්මනින් ක්රියා කරයි. පළමු සහ දෙවන ඉල්ලීම් දෙකම තත්පර 0.1 ට අඩු කාලයකින් සම්පූර්ණ වේ. ගණන් කිරීම (*) සඳහා විමසුම් ක්‍රියාත්මක කිරීමේ කාලය ලකුණු 3ක් හරහා ගමන් කිරීම පිළිබඳ උදාහරණයක් මෙන්න:

SELECT count(*)
FROM 
(
    SELECT 
        s1.person AS person, 
        s1.zone AS s1z, 
        s1.when AS s1w, 
        s2.zone AS s2z, 
        s2.when AS s2w
    FROM 
    (
        SELECT *
        FROM steps
        WHERE (area = 0) AND (zone = 0)
    ) AS s1
    ANY INNER JOIN 
    (
        SELECT *
        FROM steps AS s2
        WHERE (area = 0) AND (zone = 3)
    ) AS s2 USING (person)
    WHERE s1.when <= s2.when
) AS p
ANY INNER JOIN 
(
    SELECT *
    FROM steps
    WHERE (area = 0) AND (zone = 19)
) AS s3 USING (person)
WHERE p.s2w <= s3.when

┌─count()─┐
│   11592 │
└─────────┘

1 rows in set. Elapsed: 0.068 sec. Processed 250.03 thousand rows, 8.00 MB (3.69 million rows/s., 117.98 MB/s.)

IOPS ගැන සටහනක්. දත්ත පුරවන විට, JanusGraph තරමක් ඉහළ IOPS සංඛ්‍යාවක් (දත්ත ජනගහන නූල් හතරක් සඳහා 1000-1300) ජනනය කළ අතර IOWAIT තරමක් ඉහළ විය. ඒ සමගම, ClickHouse තැටි උප පද්ධතිය මත අවම බරක් ජනනය කළේය.

නිගමනය

මෙම ආකාරයේ ඉල්ලීම් සේවා කිරීමට අපි ClickHouse භාවිතා කිරීමට තීරණය කළෙමු. ClickHouse වෙත පූරණය කිරීමට පෙර Apache Flink භාවිතයෙන් සිදුවීම් ප්‍රවාහය පූර්ව-සැකසුම් කිරීමෙන් අපට සෑම විටම ද්‍රව්‍යමය දර්ශන සහ සමාන්තරකරණය භාවිතයෙන් විමසීම් තවදුරටත් ප්‍රශස්ත කළ හැක.

කාර්ය සාධනය කොතරම් හොඳද යත්, ක්‍රමලේඛනාත්මකව වගු හැරවීම ගැන අපට සිතීමට පවා සිදු නොවනු ඇත. මීට පෙර, අපට Vertica වෙතින් Apache Parquet වෙත උඩුගත කිරීම හරහා ලබා ගත් දත්තවල හැරීම් සිදු කිරීමට සිදු විය.

අවාසනාවකට, DBMS ප්‍රස්තාරයක් භාවිතා කිරීමට ගත් තවත් උත්සාහයක් අසාර්ථක විය. මම JanusGraph නිෂ්පාදනය සමඟ වේගවත් වීමට පහසු වන හිතකාමී පරිසර පද්ධතියක් ඇති බව සොයා ගත්තේ නැත. ඒ අතරම, සේවාදායකය වින්‍යාස කිරීම සඳහා, සාම්ප්‍රදායික ජාවා ක්‍රමය භාවිතා කරනු ලැබේ, එමඟින් ජාවා ගැන නොදන්නා පුද්ගලයින් ලේ කඳුළු සලනු ඇත:

host: 0.0.0.0
port: 8182
threadPoolWorker: 1
gremlinPool: 8
scriptEvaluationTimeout: 30000
channelizer: org.janusgraph.channelizers.JanusGraphWsAndHttpChannelizer

graphManager: org.janusgraph.graphdb.management.JanusGraphManager
graphs: {
  ConfigurationManagementGraph: conf/janusgraph-cql-configurationgraph.properties,
  airlines: conf/airlines.properties
}

scriptEngines: {
  gremlin-groovy: {
    plugins: { org.janusgraph.graphdb.tinkerpop.plugin.JanusGraphGremlinPlugin: {},
               org.apache.tinkerpop.gremlin.server.jsr223.GremlinServerGremlinPlugin: {},
               org.apache.tinkerpop.gremlin.tinkergraph.jsr223.TinkerGraphGremlinPlugin: {},
               org.apache.tinkerpop.gremlin.jsr223.ImportGremlinPlugin: {classImports: [java.lang.Math], methodImports: [java.lang.Math#*]},
               org.apache.tinkerpop.gremlin.jsr223.ScriptFileGremlinPlugin: {files: [scripts/airline-sample.groovy]}}}}

serializers:
# GraphBinary is here to replace Gryo and Graphson
  - { className: org.apache.tinkerpop.gremlin.driver.ser.GraphBinaryMessageSerializerV1, config: { ioRegistries: [org.janusgraph.graphdb.tinkerpop.JanusGraphIoRegistry] }}
  - { className: org.apache.tinkerpop.gremlin.driver.ser.GraphBinaryMessageSerializerV1, config: { serializeResultToString: true }}
  # Gryo and Graphson, latest versions
  - { className: org.apache.tinkerpop.gremlin.driver.ser.GryoMessageSerializerV3d0, config: { ioRegistries: [org.janusgraph.graphdb.tinkerpop.JanusGraphIoRegistry] }}
  - { className: org.apache.tinkerpop.gremlin.driver.ser.GryoMessageSerializerV3d0, config: { serializeResultToString: true }}
  - { className: org.apache.tinkerpop.gremlin.driver.ser.GraphSONMessageSerializerV3d0, config: { ioRegistries: [org.janusgraph.graphdb.tinkerpop.JanusGraphIoRegistry] }}
  # Older serialization versions for backwards compatibility:
  - { className: org.apache.tinkerpop.gremlin.driver.ser.GryoMessageSerializerV1d0, config: { ioRegistries: [org.janusgraph.graphdb.tinkerpop.JanusGraphIoRegistry] }}
  - { className: org.apache.tinkerpop.gremlin.driver.ser.GryoMessageSerializerV1d0, config: { serializeResultToString: true }}
  - { className: org.apache.tinkerpop.gremlin.driver.ser.GryoLiteMessageSerializerV1d0, config: {ioRegistries: [org.janusgraph.graphdb.tinkerpop.JanusGraphIoRegistry] }}
  - { className: org.apache.tinkerpop.gremlin.driver.ser.GraphSONMessageSerializerGremlinV2d0, config: { ioRegistries: [org.janusgraph.graphdb.tinkerpop.JanusGraphIoRegistry] }}
  - { className: org.apache.tinkerpop.gremlin.driver.ser.GraphSONMessageSerializerGremlinV1d0, config: { ioRegistries: [org.janusgraph.graphdb.tinkerpop.JanusGraphIoRegistryV1d0] }}
  - { className: org.apache.tinkerpop.gremlin.driver.ser.GraphSONMessageSerializerV1d0, config: { ioRegistries: [org.janusgraph.graphdb.tinkerpop.JanusGraphIoRegistryV1d0] }}

processors:
  - { className: org.apache.tinkerpop.gremlin.server.op.session.SessionOpProcessor, config: { sessionTimeout: 28800000 }}
  - { className: org.apache.tinkerpop.gremlin.server.op.traversal.TraversalOpProcessor, config: { cacheExpirationTime: 600000, cacheMaxSize: 1000 }}

metrics: {
  consoleReporter: {enabled: false, interval: 180000},
  csvReporter: {enabled: false, interval: 180000, fileName: /tmp/gremlin-server-metrics.csv},
  jmxReporter: {enabled: false},
  slf4jReporter: {enabled: true, interval: 180000},
  gangliaReporter: {enabled: false, interval: 180000, addressingMode: MULTICAST},
  graphiteReporter: {enabled: false, interval: 180000}}
threadPoolBoss: 1
maxInitialLineLength: 4096
maxHeaderSize: 8192
maxChunkSize: 8192
maxContentLength: 65536
maxAccumulationBufferComponents: 1024
resultIterationBatchSize: 64
writeBufferHighWaterMark: 32768
writeBufferHighWaterMark: 65536
ssl: {
  enabled: false}

JanusGraph හි BerkeleyDB අනුවාදය අහම්බෙන් "තැබීමට" මට හැකි විය.

දර්ශක කළමනාකරණය කිරීම සඳහා ඔබට Groovy හි තරමක් අමුතු shamanism ක්‍රියාත්මක කිරීමට අවශ්‍ය වන බැවින් ලේඛනගත කිරීම දර්ශක අනුව තරමක් වංක ය. උදාහරණයක් ලෙස, දර්ශකයක් නිර්මාණය කිරීම Gremlin කොන්සෝලයේ කේතය ලිවීමෙන් සිදු කළ යුතුය (එය මාර්ගයෙන්, කොටුවෙන් පිටත ක්රියා නොකරයි). නිල JanusGraph ලේඛනයෙන්:

graph.tx().rollback() //Never create new indexes while a transaction is active
mgmt = graph.openManagement()
name = mgmt.getPropertyKey('name')
age = mgmt.getPropertyKey('age')
mgmt.buildIndex('byNameComposite', Vertex.class).addKey(name).buildCompositeIndex()
mgmt.buildIndex('byNameAndAgeComposite', Vertex.class).addKey(name).addKey(age).buildCompositeIndex()
mgmt.commit()

//Wait for the index to become available
ManagementSystem.awaitGraphIndexStatus(graph, 'byNameComposite').call()
ManagementSystem.awaitGraphIndexStatus(graph, 'byNameAndAgeComposite').call()
//Reindex the existing data
mgmt = graph.openManagement()
mgmt.updateIndex(mgmt.getGraphIndex("byNameComposite"), SchemaAction.REINDEX).get()
mgmt.updateIndex(mgmt.getGraphIndex("byNameAndAgeComposite"), SchemaAction.REINDEX).get()
mgmt.commit()

පසු පදය

එක් අතකින්, ඉහත අත්හදා බැලීම උණුසුම් හා මෘදු අතර සංසන්දනයකි. ඔබ ඒ ගැන සිතන්නේ නම්, DBMS ප්‍රස්ථාරයක් එකම ප්‍රතිඵල ලබා ගැනීම සඳහා වෙනත් මෙහෙයුම් සිදු කරයි. කෙසේ වෙතත්, පරීක්ෂණවල කොටසක් ලෙස, මම මෙවැනි ඉල්ලීමක් සමඟ අත්හදා බැලීමක් ද සිදු කළෙමි:

g.V().hasLabel('ZoneStep').has('id',0)
    .repeat(__.out().simplePath()).until(__.hasLabel('ZoneStep').has('id',1)).count().next()

ඇවිදීමේ දුර පිළිබිඹු කරයි. කෙසේ වෙතත්, එවැනි දත්තවල පවා, ප්‍රස්ථාර DBMS තත්පර කිහිපයකින් ඔබ්බට ගිය ප්‍රති results ල පෙන්නුම් කළේය ... මෙය ඇත්ත වශයෙන්ම, වැනි මාර්ග තිබූ බැවිනි. 0 -> X -> Y ... -> 1, ප්‍රස්ථාර එන්ජිම ද පරීක්ෂා කරන ලදී.

වැනි විමසුමක් සඳහා පවා:

g.V().hasLabel('ZoneStep').has('id',0).out().has('id',1)).count().next()

තත්පරයකට වඩා අඩු සැකසුම් කාලයකින් ඵලදායී ප්‍රතිචාරයක් ලබා ගැනීමට මට නොහැකි විය.

කතාවේ සදාචාරය නම්, ලස්සන අදහසක් සහ සුසමාදර්ශීය ආකෘති නිර්මාණය අපේක්ෂිත ප්‍රතිඵලයට නොපැමිණෙන අතර, එය ClickHouse හි උදාහරණය භාවිතා කරමින් වඩා ඉහළ කාර්යක්ෂමතාවයකින් පෙන්නුම් කෙරේ. මෙම ලිපියේ ඉදිරිපත් කර ඇති භාවිත අවස්ථාව ප්‍රස්ථාර DBMS සඳහා පැහැදිලි ප්‍රති-රටාවකි.

මූලාශ්රය: www.habr.com

අදහස් එක් කරන්න