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

Database 如何有效地检查RavenDB中文档的存在性,database,database-design,nosql,data-modeling,ravendb,Database,Database Design,Nosql,Data Modeling,Ravendb,我有一个域实体Contacts,Contact通过MemberOf属性与列表关联(包含RavenDB中的列表id) 公共类联系人 { 公共字符串Id{get;set;} 公共字符串电子邮件{get;set;} 公共字符串名称{get;set;} 公共字符串国家{get;set;} {get;set;}的公共列表成员 } 我想使用RavenDB来存储联系人,上传联系人的方法之一是通过CSV文件(批量)。我在想,当两个CSV文件具有相同的联系人时,我如何防止重复数据,我认为当它们具有相同的电子邮件

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

公共类联系人
{
公共字符串Id{get;set;}
公共字符串电子邮件{get;set;}
公共字符串名称{get;set;}
公共字符串国家{get;set;}
{get;set;}的公共列表成员
}
我想使用RavenDB来存储联系人,上传联系人的方法之一是通过CSV文件(批量)。我在想,当两个CSV文件具有相同的联系人时,我如何防止重复数据,我认为当它们具有相同的电子邮件时,联系人是相同的-这与我的域逻辑有关。联系人可以是两个不同CSV列表的成员,例如,
我正在上载两个具有相同电子邮件地址字段的CSV列表,问题是我希望联系人类的MemeberOf设置为具有两个列表,这可以防止每个列表都有重复的条目,因为我的应用程序的域逻辑要求每个电子邮件有一个联系人对象用于统计分析

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


谢谢

RavenDB为您实施的唯一唯一约束是文档Id。因此,您可以使用的一种方法是将电子邮件地址设置为文档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();
}
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; }
}

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

每次导入将上载多少个文档,您希望运行多少导入以及总共需要多少文档?我下面的回答是否解决了您的问题?只要每个电子邮件地址都是唯一的联系人,我同意此解决方案。如果您希望支持电子邮件地址更改和反映同一联系人的功能,那么您将需要不同的Id。此外,else块中的session.Store()是多余的,因为已经跟踪了existingDoc。您可以删除该行以略微提高性能。最后一个注意事项是,如果您只想在不加载文档的情况下检查文档是否存在,请使用session.Advanced.DatabaseCommands.Head()。它只会加载标题,而不是整个文档。另请参阅末尾的“更新”部分,了解允许更改电子邮件地址的方法
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; }
}