如何在RavenDB中有效地检查文档的存在

时间:2022-04-27 16:26:50

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

我有一个域实体Contacts,Contact通过MemberOf属性与列表相关联(包含RavenDB中的列表ID)

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.

我想使用RavenDB存储联系人,其中一种上传联系人的方法是通过CSV文件(批量)。我在想如何在两个CSV文件具有相同的联系人时防止重复数据,我认为当他们拥有相同的电子邮件时,联系人是相同的 - 这与我的域逻辑有关。联系人可以是两个不同的CSV列表的成员,例如我上传了两个具有相同电子邮件地址字段的CSV列表,问题是我希望联系人类将MemeberOf设置为有两个列表,这样可以避免每个列表都有重复的条目,因为我的域逻辑应用程序每封电子邮件需要一个联系对象进行统

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

请挑战我的设计,我可能没有最好的数据模型。

Thank you

1 个解决方案

#1


4  

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:

RavenDB为您强制执行的唯一唯一约束是文档ID。因此,您可以使用的一种方法是将电子邮件地址设为doc Id。然后你可以编写如下代码:

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/blah@blah.co.uk), you might have to do some escaping to account for the '@' in the email address.

由于文档ID是网址(/docs/contacts/blah@blah.co.uk),因此您可能需要进行一些转义以解释电子邮件地址中的“@”。

and your POCO will look like this:

而你的POCO将如下所示:

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.

如果您不希望doc Id成为电子邮件地址(无论出于何种原因),请更新。您可以使用此处列出的方法。它每次只存储2个文档,Contact doc和另一个确保唯一约束的doc。

#1


4  

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:

RavenDB为您强制执行的唯一唯一约束是文档ID。因此,您可以使用的一种方法是将电子邮件地址设为doc Id。然后你可以编写如下代码:

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/blah@blah.co.uk), you might have to do some escaping to account for the '@' in the email address.

由于文档ID是网址(/docs/contacts/blah@blah.co.uk),因此您可能需要进行一些转义以解释电子邮件地址中的“@”。

and your POCO will look like this:

而你的POCO将如下所示:

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.

如果您不希望doc Id成为电子邮件地址(无论出于何种原因),请更新。您可以使用此处列出的方法。它每次只存储2个文档,Contact doc和另一个确保唯一约束的doc。