Как я могу избежать многих выполняемых запросов gremlin в моем C #-коде?

#c# #gremlin

#c# #gremlin

Вопрос:

У меня есть эта база данных:

Клиенты => Инцидент => Файл => Имя файла

У клиентов есть идентификатор, у инцидентов есть идентификатор и свойство reportedOn, у файлов есть идентификатор и размер файла, mimeType, свойство malware, у имен файлов есть ИДЕНТИФИКАТОР, у клиента есть исходящий край для инцидентов (сообщается), у инцидента есть исходящий край для файла (containsFile), у файла есть исходящий край для filename (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 # я проверяю каждое имя файла в базе данных на наличие специальных расширений файлов. После этого я беру имена файлов, которые имеют эти специальные расширения файлов, чтобы получить все их значения и вершины вокруг них с их значениями во втором запросе, который находится в foreachloop:

 var resultSet = await SubmitQueryAsync("g.V().hasLabel('fileName')");
                    if (resultSet.Length > 0)
                    {
                        foreach (var result in resultSet)
                        {
                        JObject jsonData = resu<
                        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);
                            }
                        }
                    }
  

Итак, для каждого имени файла, имеющего одно из специальных расширений fileextensions, я выполняю один запрос в foreachloop. Проблема в том, что это слишком много запросов к базе данных. Итак, как я могу сделать это более эффективным?

Ответ №1:

Первое, что вам, вероятно, нужно сделать, это изменить свою модель данных и включить свойство «ext» (т.Е. «FileExtension») в «fileName», чтобы вы могли легко выполнять поиск по нему (я не думаю, что CosmosDB поддерживает TextP или аналогичные опции для текстового поиска), таким образом:

 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]]
  

но это немного меняет структуру вашего возвращаемого результата. Я полагаю, что это можно было бы свести к тому, что у вас было с большим количеством преобразований, но я не уверен, что вас это беспокоит. Я просто пытаюсь помочь сделать запрос более читаемым на этом этапе.