David MZ
David MZ

Reputation: 3718

How I can efficiently check existence of a document in RavenDB

I have a domain entity Contacts, Contact is associated with lists via the MemberOf property (contains the list id in RavenDB)

public class Contact
{
    public string Id { get; set; }
    public string Email { get; set; }
    public string Name { get; set; }
    public string Country { get; set; }
    public List<string> MemberOf { get; set; }
}

I want to use RavenDB to store contacts, one of the methods to upload contacts is via CSV files (in bulk). I was thinking how can I prevent duplicate data when two CSV files have the same contacts, I consider contacts to be the same when they have the same Email - this is related to my domain logic. A Contact can be a MemberOf two different CSV lists e.g.
I am uploading two CSV lists that have the same email address field, the problem is that I want the contact class to have MemeberOf set to have two lists, this to keep me from having duplicate entries for each list, because the domain logic of my application required one contact object per email for statistical analysis.

Please challenge my design as well, I might not have the best data model here.

Thank you

Upvotes: 3

Views: 2366

Answers (1)

Matt Warren
Matt Warren

Reputation: 10291

The only unique constraint that RavenDB enforces for you is the doc Id. So one method you can use is to make the email address the doc Id. You can then write code like this:

using (var session = docStore.OpenSession())
{
    foreach (var csvItemToImport in csvfile)
    {
        var existingDoc = session.Load<Contact>(csvItemToImport.Email);    
        if (existingDoc == null)
        {
            //No doc with the given email exists, add a new one
            session.Store(new Contact{ ... });
        }
        else
        {
            existingDoc.MemberOf.Add(csvItemToImport.ListName)
            // No need to store the doc, it's tracked in the session automatically
        }     
    }
    //Save the changes so far back to the dBase, in a single batched transaction
    session.SaveChanges();
}

Because the doc Id is the url (/docs/contacts/[email protected]), you might have to do some escaping to account for the '@' in the email address.

and your POCO will look like this:

public class Contact
{
    public string Id { get; set; } //this is actually an email address 
    public string Name { get; set; }
    public string Country { get; set; }
    public List<string> MemberOf { get; set; }
}

Update if you don't want the doc Id to be the email address (for whatever reason). You can use the method outlined here. It just stores 2 docs each time, the Contact doc and another doc that ensures the unique constraint.

Upvotes: 4

Related Questions