Search code examples
c#azureazure-cosmosdbgremlin

Verify the existence of document with Azure gremlin query


I am a bit confused about something that should be a simple task, check the existence of a document by a gremlin query and if not insert the document.

Given the following function:

public static async Task StoreAuditDetail(AuditDetailResponse auditDetail, string endpointUrl, string authorizationKey)
        {
          using (var cosmosClient = new DocumentClient(new Uri(endpointUrl), authorizationKey))
          {
            const string db = "iauditor-database";
            const string collection = "audit-details";
            Uri databaseUri = UriFactory.CreateDatabaseUri(db);
            DocumentCollection graph = cosmosClient.CreateDocumentCollectionIfNotExistsAsync(
              databaseUri,
              new DocumentCollection { Id = collection },
              new RequestOptions { OfferThroughput = 400 }).Result;

            List<dynamic> q1 = cosmosClient.CreateGremlinQuery<dynamic>(graph,
                $"g.V().hasLabel('audit-details').values('audit_id')"
                ).ExecuteNextAsync().Result.ToList();
            if (!q1.Contains(auditDetail.audit_id))
            {
              try
              {
                await cosmosClient.CreateDocumentAsync(graph.DocumentsLink, auditDetail);
              }
              catch (Exception ex)
              {
                throw;
              }
            }
          }
        }

How you can see in the following screenshot, after the first execution the document is inserted as expected: enter image description here

All seems fine, but unfortunatelly if I try to rerun the function I have an ugly response:

enter image description here

The collection of ids it's always empty, what I am doing wrong?

Thanks in advance.


Solution

  • If you don't provide the key that you want to query you can't search for that key.

    So, please provide to your stored object the key that you would like to searching for.

    If you are looking for a Vertice that has a key as 'audit-details':

    $"g.V().hasLabel('audit-details')'
    

    The CreateDocumentAsync can't be:

    await cosmosClient.CreateDocumentAsync(graph.DocumentsLink, auditDetail);
    

    It should be something like this:

    await cosmosClient.CreateDocumentAsync(graph.DocumentsLink, new { label = "audit-details", detail = auditDetail } );
    

    or better:

    await cosmosClient.CreateDocumentAsync(graph.DocumentsLink, new { label = "audit-details", id = auditDetail.audit_id, detail = auditDetail } );
    

    Now you can query your document by 'label', and also directly search by 'key':

    public static async Task StoreAuditDetail(AuditDetailResponse auditDetail, string endpointUrl, string authorizationKey)
        {
          using (var cosmosClient = new DocumentClient(new Uri(endpointUrl), authorizationKey))
          {
            const string db = "iauditor-database";
            const string collection = "audit-details";
            Uri databaseUri = UriFactory.CreateDatabaseUri(db);
            DocumentCollection graph = cosmosClient.CreateDocumentCollectionIfNotExistsAsync(
              databaseUri,
              new DocumentCollection { Id = collection },
              new RequestOptions { OfferThroughput = 400 }).Result;
    
            List<dynamic> q = cosmosClient.CreateGremlinQuery<dynamic>(graph,
                $"g.V().hasLabel('audit-details').values('id')"
                ).ExecuteNextAsync().Result.ToList();
    
            if (!q.Contains(auditDetail.audit_id))
            {
              try
              {
                await cosmosClient.CreateDocumentAsync(graph.DocumentsLink, new { label = "audit-details", id = auditDetail.audit_id, detail = auditDetail } );
              }
              catch (Exception ex)
              {
                throw;
              }
            }
          }
        }