【问题标题】:Insert multiple Vertices at once using Cosmos DB Graph-API使用 Cosmos DB Graph-API 一次插入多个顶点
【发布时间】:2017-11-04 00:52:36
【问题描述】:

我希望使用 Azure Cosmos DB Graph-API 快速插入多个顶点。大多数当前的 Microsoft 示例一个一个地创建顶点并为每个顶点执行 Gremlin 查询,如下所示:

IDocumentQuery<dynamic> query = client.CreateGremlinQuery<dynamic>(graph, "g.addV('person').property('id', 'thomas').property('name', 'Thomas').property('age', 44)");

while (query.HasMoreResults)
{                    
    foreach (dynamic result in await query.ExecuteNextAsync())  {   
        Console.WriteLine($"\t {JsonConvert.SerializeObject(result)}"); 
    }
    Console.WriteLine();
}


query = client.CreateGremlinQuery<dynamic>(graph, "g.addV('person').property('id', 'mary').property('name', 'Mary').property('lastName', 'Andersen').property('age', 39)");

while (query.HasMoreResults)
{                    
    foreach (dynamic result in await query.ExecuteNextAsync())  {   
        Console.WriteLine($"\t {JsonConvert.SerializeObject(result)}"); 
    }
    Console.WriteLine();
}

但是,当我想创建几千个顶点和边来初始填充图形时,这并不理想,因为这可能需要一些时间。

这是 Microsoft.Azure.Graphs 库 v0.2.0-preview

如何有效地将多个顶点一次添加到 Cosmos DB,以便以后可以使用 Graph API 语法进行查询?

【问题讨论】:

    标签: gremlin azure-cosmosdb


    【解决方案1】:

    我发现,为图表播种的最快方法实际上是使用 Document API。利用这种技术,我已经能够在一台开发机器上每秒插入 5500 多个顶点/边。诀窍是了解 Cosmos 对边和顶点的期望格式。只需通过 gremlin API 将几个顶点和边添加到您的图形中,然后通过转到 Azure 中的数据资源管理器并对 SELECT * FROM c 执行文档查询来检查这些文档的格式。

    在工作中,我构建了一个轻量级 ORM,它使用反射来获取边缘和顶点的 POCO,并将它们转换为您在门户中看到的格式。我希望尽快开源,届时我很可能会发布一个 Nuget 包和随附的博客文章。希望在此期间,这将有助于为您指明正确的方向,如果您对此方法有更多疑问,请告诉我。

    【讨论】:

    • 我正在尝试仅使用一个 CreateDocument 调用来插入顶点和边,但结果是我的图表丢弃了大部分值。你能分享你上传的东西来创建对象吗?谢谢!
    • @MuriloMacielCurti 我有同样的问题,但在我的情况下属性/值没有丢失,当我使用文档 db api 检索它们时我得到了它们。但它们在 azure graph ui 中不可见。在我的例子中,它显示了正确的 id 和一个值为“NativeVertex”的标签,而不是属性。不幸的是,我无法找到有关此的更多详细信息。
    • @JesseCarter 你能分享更多吗?谢谢ChiefWiggum
    • 一旦你得到了正确的graphSON,你怎么把它作为一个graph上传呢?我尝试了 migraiton 工具但没有成功。
    • @JesseCarter 你发布了上述 ORM 吗?
    【解决方案2】:

    假设 CosmosDB 100% 兼容 TinkerPop,并且根据 gremlin 执行程序超时设置,您应该能够更新 gremlin 脚本以一次执行多项操作。

    例如:

    g.addV('person').property('id', 'mary').property('name', 'Mary').property('lastName', 'Andersen').property('age', 39)

    可以转化为:

    g.addV('person').property('id', 'mary').property('name', 'Mary').property('lastName', 'Andersen').property('age', 39); g.addV('person').property('id', 'david').property('name', 'David').property('lastName', 'P').property('age', 24);

    等等等等

    您的 gremlin 脚本也只是 Groovy 代码,因此您甚至可以编写循环以及不能创建顶点、附加属性等的内容。

    【讨论】:

    • 谢谢,我怀疑应该可以用分号分隔多个 g.addV 语句,正如您在回答中指出的那样,但是 CosmosDb Graph API 似乎只运行第一个语句而不是任何后续的。例如,运行分号分隔的 addV 然后在空集合上运行 g.V().count() 仅返回 1。也许这是 CosmosDB Graph API 实现所特有的?
    • 如果这是真的,我会感到非常惊讶。这个客户端代码是开源的吗?您可以查看并阅读那里的代码,以了解它如何处理您提交的脚本。但我真的会想象它只是将确切的脚本转发到 GremlinServer。
    • 感谢您的建议。 SDK 的源代码看起来还不是开源的。然而,我确实启动了 Fiddler 并查看 CosmosDB Graph API 发送到服务器的内容。它看起来不像为 addV 发送 Gremlin 脚本,但它为要插入的对象发送 JSON。所以看起来客户端库做了一些转换。对于一个简单的 g.V().count() 它通过 JSON 发送一个查询,格式为 {"query":"SELECT N_0 FROM Node N_0 WHERE (IS_DEFINED(N_0._isEdge) = false )"}
    【解决方案3】:

    我们需要一个工具来帮助我们将数据迁移到 cosmosdb 图表,但由于没有可用的数据,我最终创建了这个 - https://github.com/microsoft/migratetograph

    您可以使用它从一些 sql 或 json 中获取数据,对其进行转换并将其推送到图形数据库。 它支持 gremlin 查询的并行执行,因此速度相当快。
    默认情况下,它会并行触发 10 个 gremlin 查询,但您可以通过在 graph-config 文件中传递 batchSize 来增加它

    【讨论】:

      【解决方案4】:

      数据迁移工具可能支持 SQL API 或 MongoDB 方案,但在此阶段它不支持图形 api Vertex - Edges。如前所述,您可能会使用生成的图形查询结果作为主要参考模式,然后在您的源上进行一些搜索和替换...以最终得到正确的格式...尽管我发现只需运行控制台应用程序流数据可能是更充分。我能够在 Marvel 和 Airport 航班场景中重用相同的控制台应用程序,而我需要做的只是每次修改几行代码。 代码以 2 个序列运行。第一个块提取并转换顶点。第二个序列提取字段关系并将其转换为边缘。我需要修改的只是我需要提取的字段。这可能需要一些时间来转换,具体取决于数据的大小,尽管它每次都能给我准确的预期结果,而无需在源头不断修改数据?。

      【讨论】:

        【解决方案5】:

        我正在使用此代码通过 NodeJS 插入多个顶点

        const __ = gremlin.process.statics;
        let trt = await g.withBulk(true).V('test-3').fold().coalesce(__.unfold().property(gremlin.process.cardinality.single, 'runways', 4), __.addV('truongtest').property(gremlin.process.t.id, 'test-3').property(gremlin.process.cardinality.single, 'runways', 4))
                .V('test-10').fold().coalesce(__.unfold().property(gremlin.process.cardinality.single, 'runways', 100), __.addV('truongtest').property(gremlin.process.t.id, 'test-10').property(gremlin.process.cardinality.single, 'runways', 100))
                .next()
                
        // if you wanna add alot , using loop 
        
        let trt = await g.withBulk(true)
        trt = trt.V('test-3').fold().coalesce(__.unfold().property(gremlin.process.cardinality.single, 'runways', 4), __.addV('truongtest').property(gremlin.process.t.id, 'test-3').property(gremlin.process.cardinality.single, 'runways', 4))
                
        trt = trt.V('test-10').fold().coalesce(__.unfold().property(gremlin.process.cardinality.single, 'runways', 100), __.addV('truongtest').property(gremlin.process.t.id, 'test-10').property(gremlin.process.cardinality.single, 'runways', 100))
        
        // after done run next()
        trt.next()

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2018-10-25
          • 1970-01-01
          • 2020-01-19
          • 1970-01-01
          • 1970-01-01
          • 2019-01-23
          • 2021-11-08
          • 1970-01-01
          相关资源
          最近更新 更多