#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]]
но это немного меняет структуру вашего возвращаемого результата. Я полагаю, что это можно было бы свести к тому, что у вас было с большим количеством преобразований, но я не уверен, что вас это беспокоит. Я просто пытаюсь помочь сделать запрос более читаемым на этом этапе.