0

I'm working with Neo4j Driver and trying to read and write from the DB locally.

Writing to the DB works with:

try
{
   List<Person> people = CollectPeopleData();

   _driver = GraphDatabase.Driver(uri, AuthTokens.Basic(userName, password));

   using var session = _driver.AsyncSession();
            
   foreach (Person person in people)
   {
        var data = session.ExecuteWriteAsync(tx =>
           {
                   var result = tx.RunAsync(
                        "CREATE (a:Person) " +
                        "SET a.id = $person.Id " +
                        "SET a.name = $person.Name " +
                        "RETURN a.Id",
                        new { person });

                    return result;
                });
            }
 }
 catch (Exception ex)
 {
      Console.WriteLine(ex.StackTrace);
 }

The above code works. I can write to the DB. If I try to do the same with session.ExecuteReadAsync() to read instead of write it doesn't work (the DB contains a bunch of nodes already).

I can't seem to process the Task<IResultCursor>, even if I convert it to a list of IRecords by doing data.Result.ToListAsync(), it seems to tell me that the records have already been consumed..? Can't really figure out the best or working minimal example to retrieve data from my DB.

Code attempted:

try
{
    _driver = GraphDatabase.Driver(uri, AuthTokens.Basic(userName, password));
    using var session = _driver.AsyncSession();              
    
    Task<IResultCursor> data = session.ExecuteReadAsync(tx =>
    {
        Task<IResultCursor> result = tx.RunAsync(
            "MATCH (a) " +
            "RETURN a"
        );

        return result;
    }

    data.Result.ForEachAsync(x => Console.WriteLine(x.Values.ToString()));
}
catch (Exception ex)
{
    Console.WriteLine(ex.StackTrace);
}

Perhaps someone can suggest a simple example to just get all data as objects with "MATCH (n) RETURN (n)"? i.e. I don't need to do any complex filtering, I just want the records and then do stuff with them later.

Yafim Simanovsky
  • 531
  • 7
  • 26
  • Ihave similar issue in python and once data is fetched, you cannot use it again. The data in the session is gone after fetching it. The fix I did is to save the resulting data into another variable then I can re-use that data throughout my code. – jose_bacoy Sep 27 '22 at 11:34
  • Pls show us your code that is NOT working. The one that uses session.ExecuteReadAsync() and data.Result.ToListAsync(). Thanks – jose_bacoy Sep 27 '22 at 11:37
  • @jose_bacoy hi thanks! plz check edit for attempted code. I tried also to assign the `ToListAsync()` to a variable that is defined above the session and to loop that after, i.e. your solution..? didn't work either... can you perhaps share the code of what you did? tnx – Yafim Simanovsky Sep 27 '22 at 13:24

1 Answers1

0

This is UNTESTED. Kindly try the code below and add the step to print out the result in the console. Thanks.

try
 {
    _driver = GraphDatabase.Driver(uri, AuthTokens.Basic(userName, password));
  // Open a new session.
  await using var session = _driver.AsyncSession();

  // Execute a query in a new Read Transaction.
  return await session.ReadTransactionAsync(async tx =>
  {
      var cursor = await tx.RunAsync(@$"
          MATCH (m:Movie)
          WHERE m.title IS NOT NULL
          RETURN m {{ .* }} AS movie
          LIMIT 5");

      var records = await cursor.ToListAsync();
      var movies = records
          .Select(x => x["movie"].As<Dictionary<string, object>>())
          .ToArray();   

      return movies;
  });
  }
catch (Exception ex)
{
    Console.WriteLine(ex.StackTrace);
}
jose_bacoy
  • 12,227
  • 1
  • 20
  • 38