【问题标题】:How can I avoid to many executed gremlinqueries in my C#-Code?如何避免在我的 C# 代码中执行许多已执行的 gremlinqueries?
【发布时间】:2019-04-12 07:19:05
【问题描述】:

我有这个数据库:

客户 => 事件 => 文件 => 文件名

客户有一个 ID 事件有一个 ID 和一个reportedOn 属性 文件具有 ID 和 fileSize、mimeType、恶意软件属性 文件名有一个 ID 客户端有一个传出边缘到事件(报告),事件有一个传出边缘到文件(包含文件),文件有一个传出边缘到文件名(hasName)。

这是一些示例数据:

g.addV('client').property('id','1').as('1').
  addV('incident').property('id','11').property('reportedON', '2/15/2019 8:01:19 AM').as('11').
  addV('file').property('id','100').property('fileSize', '432534').as('100').
  addV('fileName').property('id','file.pdf').as('file.pdf').
  addE('reported').from('1').to('11').
  addE('containsFile').from('11').to('100').
  addE('hasName').from('100').to('file.pdf').iterate()

在下面的 C# 代码中,我正在检查数据库中的每个文件名是否有特殊的文件扩展名。之后,我使用具有这些特殊文件扩展名的文件名来获取它们的所有值以及它们周围的顶点以及它们在 foreach 循环中的第二个查询中的值:

var resultSet = await SubmitQueryAsync("g.V().hasLabel('fileName')");
                    if (resultSet.Length > 0)
                    {
                        foreach (var result in resultSet)
                        {
                        JObject jsonData = result;
                        string fileId = jsonData["Id"].Value<string>();
                        string fileExtension = "";
                            string[] fileExtensions = { ".ace", ".arj", ".iso", ".rar", ".gz", ".acrj", ".lnk", ".z", ".tar", ".xz" };
                            HashSet<string> hSet = new HashSet<string>(fileExtensions);

                            if (fileId.Contains("."))
                            {
                                fileExtension = fileId.Substring(fileId.LastIndexOf('.'));
                            }


                            if (hSet.Contains(fileExtension))
                            {
                            var resultSet2 = await SubmitQueryAsync("g.V().has(id, '" + fileId + "').as('FILENAME').in('hasName').as('FILE').in('containsFile').as('INCIDENT').select('FILE').valueMap().as('FILEVALUES').select('INCIDENT').valueMap().as('INCIDENTVALUES').select('FILE', 'FILEVALUES', 'FILENAME', 'INCIDENTVALUES')");
                            list = FillList(list, resultSet2);
                            }
                        }
                    }

因此,对于每个具有特殊文件扩展名之一的文件名,我在 foreach 循环中执行一个查询。问题是对数据库的查询太多了。那么如何才能提高效率呢?

【问题讨论】:

    标签: c# gremlin


    【解决方案1】:

    您可能需要做的第一件事是更改数据模型并在“fileName”上包含“ext”(即“fileExtension”)属性,以便您可以轻松搜索(我认为 CosmosDB 不支持 @ 987654321@ 或用于文本搜索的类似选项),因此:

    g.addV('client').property('id','1').as('1').
      addV('incident').property('id','11').property('reportedON', '2/15/2019 8:01:19 AM').as('11').
      addV('file').property('id','100').property('fileSize', '432534').as('100').
      addV('fileName').property('id','file.pdf').property('ext','.pdf').as('file.pdf').
      addE('reported').from('1').to('11').
      addE('containsFile').from('11').to('100').
      addE('hasName').from('100').to('file.pdf').iterate() 
    

    然后,将所有 C# 滚动到一个 Gremlin 遍历中非常简单:

    gremlin> g.V().has('fileName','ext',within(".ace", ".arj", ".iso", ".rar", ".gz", ".acrj", ".lnk", ".z", ".tar", ".xz", ".pdf")).as('FILENAME').
    ......1>   in('hasName').as('FILE').
    ......2>   in('containsFile').as('INCIDENT').
    ......3>   select('FILE').valueMap().as('FILEVALUES').
    ......4>   select('INCIDENT').valueMap().as('INCIDENTVALUES').
    ......5>   select('FILE', 'FILEVALUES', 'FILENAME', 'INCIDENTVALUES')
    ==>[FILE:v[5],FILEVALUES:[fileSize:[432534],id:[100]],FILENAME:v[8],INCIDENTVALUES:[reportedON:[2/15/2019 8:01:19 AM],id:[11]]]
    

    请注意,我将“.pdf”添加到您的“扩展”列表中,以便根据您的示例数据返回结果。除此之外,我认为您的查询确实比它应该更复杂 - 让我们尝试简化,因为所有步骤标签都使得这很难理解。我更喜欢使用project()

    gremlin> g.V().has('fileName','ext',within(".ace", ".arj", ".iso", ".rar", ".gz", ".acrj", ".lnk", ".z", ".tar", ".xz", ".pdf")).
    ......1>   project('FILE','FILEVALUES','FILENAME','INCIDENTVALUES').
    ......2>     by(__.in('hasName')).
    ......3>     by(__.in('hasName').valueMap()).
    ......4>     by().
    ......5>     by(__.in('hasName').in('containsFile').valueMap())
    ==>[FILE:v[5],FILEVALUES:[fileSize:[432534],id:[100]],FILENAME:v[8],INCIDENTVALUES:[reportedON:[2/15/2019 8:01:19 AM],id:[11]]]
    

    这让我意识到“FILE”和“FILEVALUES”基本上是一回事,可以组合:

    gremlin> g.V().has('fileName','ext',within(".ace", ".arj", ".iso", ".rar", ".gz", ".acrj", ".lnk", ".z", ".tar", ".xz", ".pdf")).
    ......1>   project('FILEVALUES','FILENAME','INCIDENTVALUES').
    ......2>     by(__.in('hasName').valueMap(true)).
    ......3>     by().
    ......4>     by(__.in('hasName').in('containsFile').valueMap())
    ==>[FILEVALUES:[id:5,fileSize:[432534],id:[100],label:file],FILENAME:v[8],INCIDENTVALUES:[reportedON:[2/15/2019 8:01:19 AM],id:[11]]]
    

    我不喜欢我们这样遍历in('hasName') 两次:

    gremlin> g.V().has('fileName','ext',within(".ace", ".arj", ".iso", ".rar", ".gz", ".acrj", ".lnk", ".z", ".tar", ".xz", ".pdf")).
    ......1>   project('FILEVALUES','FILENAME').
    ......2>     by(__.in('hasName').
    ......3>        project('FILE','INCIDENT').
    ......4>          by(valueMap(true)).
    ......5>          by(__.in('containsFile').valueMap())).
    ......6>     by()
    ==>[FILEVALUES:[FILE:[id:5,fileSize:[432534],id:[100],label:file],INCIDENT:[reportedON:[2/15/2019 8:01:19 AM],id:[11]]],FILENAME:v[8]]
    

    但这会稍微改变返回结果的结构。我想这可以通过更多的转换恢复到你所拥有的,但我不确定你是否担心这一点。在这一点上,我只是想帮助使查询更具可读性。

    【讨论】:

      猜你喜欢
      • 2012-08-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-06
      • 2014-05-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多