مناسب رستا ڳولڻ جي مسئلي کي حل ڪرڻ لاء JanusGraph گراف DBMS جي قابل اطلاق جي جانچ ڪندي.

مناسب رستا ڳولڻ جي مسئلي کي حل ڪرڻ لاء JanusGraph گراف DBMS جي قابل اطلاق جي جانچ ڪندي.

هيلو سڀ. اسان آف لائن ٽرئفڪ جي تجزيو لاءِ پراڊڪٽ ٺاهي رهيا آهيون. پروجيڪٽ ۾ علائقن جي گهمڻ وارن رستن جي شمارياتي تجزيي سان لاڳاپيل ڪم آهي.

ھن ڪم جي حصي جي طور تي، صارفين ھيٺ ڏنل قسم جا سسٽم سوال پڇي سگھن ٿا:

  • ڪيترا سياحن "A" کان علائقي "B" تائين گذري ويا؛
  • ڪيترا سياح "اي" کان ايريا "بي" تائين ايريا "سي" ذريعي ۽ پوء ايريا "ڊي" ذريعي گذريا آهن؛
  • هڪ خاص قسم جي سياحن کي علائقي ”A“ کان علائقي ”B“ تائين سفر ڪرڻ ۾ ڪيترو وقت لڳي ويو.

۽ اهڙا ڪيترائي تجزياتي سوال.

علائقن ۾ دورو ڪندڙ جي حرڪت هڪ هدايت ٿيل گراف آهي. انٽرنيٽ پڙهڻ کان پوء، مون دريافت ڪيو ته گراف ڊي بي ايم ايس پڻ تجزياتي رپورٽن لاء استعمال ڪيا ويا آهن. مون کي ڏسڻ جي خواهش هئي ته گراف ڊي بي ايم ايس اهڙين سوالن کي ڪيئن منهن ڏيندو (TL؛ DR؛ خراب).

مون DBMS استعمال ڪرڻ جو انتخاب ڪيو جينس گراف، گراف اوپن سورس DBMS جي هڪ شاندار نمائندي جي طور تي، جيڪو پختو ٽيڪنالاجيز جي اسٽيڪ تي ڀاڙي ٿو، جنهن کي (منهنجي راءِ ۾) ان کي مهذب آپريشنل خاصيتن سان مهيا ڪرڻ گهرجي:

  • BerkeleyDB اسٽوريج پس منظر، Apache Cassandra، Scylla؛
  • پيچيده انڊيڪس لوسن، ايلسٽسٽڪ سرچ، سولر ۾ محفوظ ڪري سگھجن ٿا.

JanusGraph جي ليکڪن لکي ٿو ته اهو OLTP ۽ OLAP ٻنهي لاءِ موزون آهي.

مون BerkeleyDB، Apache Cassandra، Scylla ۽ ES سان ڪم ڪيو آهي، ۽ اهي پروڊڪٽس اڪثر ڪري اسان جي سسٽم ۾ استعمال ٿينديون آهن، تنهن ڪري مان هن گراف ڊي بي ايم ايس کي جانچڻ بابت پراميد هوس. مون کي اهو عجيب لڳو ته BerkeleyDB کي RocksDB تي چونڊيو، پر اهو شايد ٽرانزيڪشن جي گهرج جي ڪري. ڪنهن به صورت ۾، اسپيبلبل، پراڊڪٽ جي استعمال لاء، اهو تجويز ڪيو ويو آهي ته هڪ پس منظر استعمال ڪيو وڃي Cassandra يا Scylla تي.

مون Neo4j تي غور نه ڪيو ڇو ته ڪلسترنگ کي تجارتي ورزن جي ضرورت آهي، اهو آهي، پراڊڪٽ اوپن سورس ناهي.

گراف ڊي بي ايم ايس چوي ٿو: "جيڪڏهن اهو گراف وانگر نظر اچي ٿو، ان کي گراف وانگر علاج ڪريو!" - خوبصورتي!

پهرين، مون هڪ گراف ٺاهيو، جيڪو بلڪل گراف ڊي بي ايم ايس جي ڪينن جي مطابق ٺاهيو ويو هو:

مناسب رستا ڳولڻ جي مسئلي کي حل ڪرڻ لاء 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 سان هڪ زون ڳولهيو، اهي سڀئي چوڪيون وٺو جتان هڪ ڪنڊ ان ڏانهن وڃي ٿو (زون اسٽيپ)، پوئتي وڃڻ کان سواءِ اسٽمپ ڪريو جيستائين توهان انهن زون اسٽيپس کي نه ڳوليو جتان زون ڏانهن هڪ ڪنڊ آهي. ID = 19، انگ ڳڻيو جيئن زنجيرن.

مان گرافس تي ڳولڻ جي سڀني پيچيدگين کي ڄاڻڻ جو ارادو نٿو ڪريان، پر هي سوال هن ڪتاب جي بنياد تي پيدا ڪيو ويو آهي (https://kelvinlawrence.net/book/Gremlin-Graph-Guide.html).

مون 50 هزار ٽريڪ لوڊ ڪيا جن جي ڊيگهه 3 کان 20 پوائنٽس تائين آهي هڪ JanusGraph ڊيٽابيس ۾ BerkeleyDB backend استعمال ڪندي، انڊيڪس ٺاهيا. قيادت.

پٿون ڊائون لوڊ اسڪرپٽ:


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)

اسان هڪ ايس ايس ڊي تي 4 ڪور ۽ 16 GB ريم سان VM استعمال ڪيو. JanusGraph هن حڪم کي استعمال ڪندي لڳايو ويو:

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

انهي صورت ۾، ڊيٽا ۽ انڊيڪس جيڪي استعمال ڪيا ويا آهن درست ميچ ڳولها لاء برڪلي ڊي بي ۾ ذخيرو ٿيل آهن. اڳ ۾ ڏنل درخواست تي عمل ڪرڻ کان پوء، مون کي ڪيترن ئي ڏهن سيڪنڊن جي برابر وقت مليو.

متوازي ۾ 4 مٿين اسڪرپٽ کي هلائڻ سان، مون ڊي بي ايم ايس کي ڪدو ۾ تبديل ڪرڻ جو انتظام ڪيو، جاوا اسٽيڪ ٽريسز جي خوشگوار وهڪري سان (۽ اسان سڀني کي جاوا اسٽيڪ ٽريسس پڙهڻ پسند آهي) ڊڪر لاگز ۾.

ڪجهه سوچڻ کان پوء، مون فيصلو ڪيو ته هيٺ ڏنل گراف ڊاگرام کي آسان ڪرڻ:

مناسب رستا ڳولڻ جي مسئلي کي حل ڪرڻ لاء JanusGraph گراف DBMS جي قابل اطلاق جي جانچ ڪندي.

اهو فيصلو ڪيو ته ڳولا جي خاصيتن جي ڳولا ڪنارن جي ڳولا کان تيز ٿي ويندي. نتيجي طور، منهنجي درخواست ھيٺين ۾ تبديل ٿي وئي:

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

روسي ۾ ڇا ڪجهه هن طرح آهي: ID = 0 سان ZoneStep ڳولھيو، بغير واپس وڃڻ کان سواء اسٽمپ ڪريو جيستائين توھان ZoneStep سان ID = 19 ڳوليو، اھڙين زنجيرن جو تعداد ڳڻيو.

مون مٿي ڏنل لوڊنگ اسڪرپٽ کي پڻ آسان ڪيو آهي ته جيئن غير ضروري ڪنيڪشن نه ٺاهي، پاڻ کي خاصيتن تائين محدود ڪري.

درخواست اڃا تائين مڪمل ٿيڻ ۾ ڪيترائي سيڪنڊ ورتي، جيڪا اسان جي ڪم لاءِ مڪمل طور تي ناقابل قبول هئي، ڇاڪاڻ ته اها ڪنهن به قسم جي AdHoc درخواستن جي مقصدن لاءِ بلڪل مناسب نه هئي.

مون ڪوشش ڪئي JanusGraph کي استعمال ڪندي Scylla کي تيز ترين Cassandra تي عمل ڪرڻ جي طور تي، پر ان سان پڻ ڪارڪردگي ۾ ڪا خاص تبديلي نه آئي.

تنهن ڪري ان حقيقت جي باوجود ته "اهو هڪ گراف وانگر ڏسڻ ۾ اچي ٿو"، مان گراف حاصل نه ڪري سگهيو آهيان DBMS ان کي جلدي پروسيس ڪرڻ لاءِ. مان مڪمل طور تي فرض ڪريان ٿو ته اتي ڪجھھ آھي جيڪو مون کي خبر نه آھي ۽ اھو JanusGraph ھڪڙي سيڪنڊ جي ھڪڙي حصي ۾ ھن ڳولا کي انجام ڏيڻ لاءِ ٺاھيو وڃي ٿو، جيتوڻيڪ، مان اھو ڪرڻ جي قابل نه ھوس.

جيئن ته مسئلو اڃا حل ٿيڻ جي ضرورت آهي، مون جدولن جي JOINs ۽ Pivots بابت سوچڻ شروع ڪيو، جيڪي خوبصورتي جي لحاظ کان اميد پسندي کي متاثر نه ڪن، پر عملي طور تي هڪ مڪمل طور تي قابل عمل اختيار ٿي سگهي ٿو.

اسان جو پروجيڪٽ اڳ ۾ ئي استعمال ڪري ٿو Apache ClickHouse، تنهن ڪري مون فيصلو ڪيو ته منهنجي تحقيق کي جانچڻ لاءِ هن تجزياتي DBMS تي.

هڪ سادي ترڪيب استعمال ڪندي ڪلڪ هاؤس کي ترتيب ڏنو:

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
    )

جيئن ته داخلائون بيچ ۾ اچن ٿيون، جانوس گراف جي ڀيٽ ۾ ڀرڻ تمام تيز هو.

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 استعمال ڪرڻ جو فيصلو ڪيو. اسان هميشه سوالن کي وڌيڪ بهتر ڪري سگھون ٿا مواد جي نظارن ۽ برابري کي استعمال ڪندي ايونٽ اسٽريم کي پري پروسيس ڪندي Apache Flink استعمال ڪرڻ کان پهريان انهن کي ClickHouse ۾ لوڊ ڪرڻ کان.

ڪارڪردگي ايتري سٺي آهي ته اسان کي شايد پروگرام جي طور تي پائيوٽنگ ٽيبل بابت سوچڻ جي ضرورت ناهي. اڳي، اسان کي اپلوڊ ذريعي ورٽيڪا مان حاصل ڪيل ڊيٽا جا محور ڪرڻا هئا Apache Parquet تي.

بدقسمتي سان، گراف ڊي بي ايم ايس استعمال ڪرڻ جي هڪ ٻي ڪوشش ناڪام ٿي. مون کي نه مليو 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}

مان جانس گراف جي برڪلي ڊي بي ورزن کي حادثاتي طور تي ”پڙهڻ“ ۾ منظم ڪيو.

دستاويز انڊيڪسز جي لحاظ کان ڪافي ڪڙي آهي، ڇاڪاڻ ته انڊيڪسس کي منظم ڪرڻ لاءِ توهان کي گرووي ۾ ڪجهه عجيب شرمناڪ ڪم ڪرڻ جي ضرورت آهي. مثال طور، هڪ انڊيڪس ٺاهڻ لازمي آهي ڪوڊ لکڻ سان 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()

پوء

هڪ لحاظ کان، مٿي ڄاڻايل تجربو گرم ۽ نرم جي وچ ۾ مقابلو آهي. جيڪڏهن توهان ان جي باري ۾ سوچيو ٿا، هڪ گراف ڊي بي ايم ايس ساڳئي نتيجن کي حاصل ڪرڻ لاء ٻين عملن کي انجام ڏئي ٿو. بهرحال، تجربن جي حصي جي طور تي، مون پڻ هڪ درخواست سان گڏ هڪ تجربو ڪيو جيئن:

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

جيڪو پنڌ جي مفاصلي کي ظاهر ڪري ٿو. بهرحال، اهڙي ڊيٽا تي به، گراف ڊي بي ايم ايس نتيجا ڏيکاريا جيڪي ڪجهه سيڪنڊن کان اڳتي نڪري ويا... اهو، يقيناً، ان حقيقت جي ڪري آهي ته اهڙا رستا هئا. 0 -> X -> Y ... -> 1جنهن کي گراف انجڻ به چيڪ ڪيو.

جيتوڻيڪ هڪ سوال لاءِ جهڙوڪ:

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

مان هڪ سيڪنڊ کان به گهٽ وقت جي پروسيسنگ وقت سان پيداواري جواب حاصل ڪرڻ کان قاصر هو.

ڪهاڻيءَ جي اخلاقي خوبي اها آهي ته هڪ خوبصورت خيال ۽ تمثيل واري ماڊلنگ گهربل نتيجو نه پهچندي آهي، جنهن کي ڪلڪ هائوس جو مثال استعمال ڪندي تمام اعليٰ ڪارڪردگيءَ سان ڏيکاريو ويو آهي. هن آرٽيڪل ۾ پيش ڪيل استعمال ڪيس گراف ڊي بي ايم ايسز لاءِ واضح مخالف نمونو آهي، جيتوڻيڪ اهو لڳي ٿو ته انهن جي پيراڊم ۾ ماڊلنگ لاءِ مناسب.

جو ذريعو: www.habr.com

تبصرو شامل ڪريو