Оператор сбора запросов Neo4jClient Cypher с несколькими значениями

я пытаюсь преобразовать запрос из шифра, чтобы использовать API-интерфейс neo4jclient в С#

Вот мой шифр

start server=node:node_auto_index(serverId='SHO2K3MS49')
MATCH 
 server-[:IS_SERVER_TYPE]->type,
 appEnv-[:HAS_SERVER]->server,
 app-[:HAS_ENV]->appEnv
return        
   server.serverId,
   collect([
   appEnv.environmentTypeId,
   appEnv.appEnvId,
   app.appId,
   app.appName
  ]) ;

Запрос возвращает одну строку для каждого сервера и собирает все приложения на этом сервере.

Насколько я вижу, API .CollectAs допускает только одиночные значения.

Идея, как это сделать с .net API?

ИЗМЕНИТЬ

я только что попробовал этот запрос

_connectedClient
 .Cypher                 
 .Start(new {server = Node.ByIndexLookup("node_auto_index", "serverId", "SHO2K3MS49") })
 .Match("server-[:IS_SERVER_TYPE]->type", "appEnv-[:HAS_SERVER]->server", "app-[:HAS_ENV]->appEnv")               
 .Return((server, appEnv, app) => 
  new
   {
       ServerName = Return.As<string>("server.serverId"),     
       aa = Return.As<dynamic>    ("collect([appEnv.environmentTypeId,appEnv.appEnvId,app.appId,app.appName])")                                                                                                                          
   })
 .Results;

и получил этот результат.

трассировка стека

at Neo4jClient.Serialization.CypherJsonDeserializer`1.Deserialize(String content)
   at Neo4jClient.GraphClient.<>c__DisplayClass1e`1.<Neo4jClient.IRawGraphClient.ExecuteGetCypherResultsAsync>b__1d(Task`1 responseTask)
   at System.Threading.Tasks.ContinuationResultTaskFromResultTask`2.InnerInvoke()
   at System.Threading.Tasks.Task.Execute()

внутреннее исключение

Accessed JArray values with invalid key value: "data". Array position index expected

сообщение – для краткости удален шаблонный текст.

Neo4jClient encountered an exception while deserializing the response from the server. This is likely a bug in Neo4jClient.

Include the full type definition of <>f__AnonymousType1`2[[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.Object, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]].

Include this raw JSON, with any sensitive values replaced with non-sensitive equivalents:

{"columns":["ServerName","aa"],"data":[["SHO2K3MS49",[["PRD","MATT.PRD","MATT","MATT"],["PRD","ARCSERV.PRD","ARCSERV","ArcServ"],["PRD","ACTIVE DIRECTORY _WINDOWS SERVER NETWORKING_.PRD","ACTIVE DIRECTORY _WINDOWS SERVER NETWORKING_","Active Directory (Windows Server networking)"]]]]}
Parameter name: content

person Matt Ritchie    schedule 26.08.2013    source источник


Ответы (1)


Это потому, что результаты, которые вы возвращаете из оператора collect, в основном представляют собой строки без определяющих столбцов. JSON.NET не может определить, что это за столбцы (и вы не можете использовать AS, чтобы помочь ему), поэтому все, что вы получаете, это строки вроде:

"[\r\n"EnvType1",\r\n"AppEnvId1",\r\n"App2",\r\n"App 2"\r\n]"

Который вы можете получить, используя следующий запрос:

_connectedClient
    .Cypher                 
    .Start(new {server = Node.ByIndexLookup("node_auto_index", "serverId", "SHO2K3MS49") })
    .Match("server-[:IS_SERVER_TYPE]->type", "appEnv-[:HAS_SERVER]->server", "app-[:HAS_ENV]->appEnv")               
     .Return((server, appEnv, app) => 
      new
       {
           ServerName = Return.As<string>("server.serverId"),     
           aa = Return.As<IEnumerable<string>>("collect([appEnv.environmentTypeId,appEnv.appEnvId,app.appId,app.appName])")                                                                                                                          
       })
     .Results;

Я изменил возвращаемый тип свойства aa на IEnumerable<string>.

Другой маршрут — использовать GroupBy после получения данных:

var query2 = GraphClient
    .Cypher
    .Start(new { server = new NodeReference(1) })
    .Match("server-[:IS_SERVER_TYPE]->type", "appEnv-[:HAS_SERVER]->server", "app-[:HAS_ENV]->appEnv")
    .Return((server, appEnv, app) =>
        new
        {
            ServerId = Return.As<string>("server.ServerId"),
            EnvironmentTypeId = Return.As<string>("appEnv.EnvironmentTypeId"),
            AppEnvId = Return.As<string>("appEnv.AppEnvId"),
            AppId = Return.As<string>("app.AppId"),
            AppName = Return.As<string>("app.AppName"),
        });

var results2 = query2.Results.GroupBy(g => g.ServerId).ToList();

Что, я думаю, даст вам результаты так, как вы хотите, я думаю, здесь вопрос в том, будет ли более эффективно выполнять collect на сервере или GroupBy на клиенте...

person Charlotte Skardon    schedule 27.08.2013