处理RavenDB中相关文档的查询

处理RavenDB中相关文档的查询,ravendb,Ravendb,我有一个项目,我有一套表格: public class Form { public string Id { get; set; } public string Name { get; set; } public IList<string> FieldValueIds { get; set; } public string UserId { get; set; } // the user who completed the form. publi

我有一个项目,我有一套表格:

public class Form
{
    public string Id { get; set; }
    public string Name { get; set; }
    public IList<string> FieldValueIds { get; set; }
    public string UserId { get; set; } // the user who completed the form.
    public string FormTemplateId { get; set; }
}
存储有关字段的信息,例如描述及其所需类型。每个FormField可以存在于多个FormTemplates中,表单的值存储为与表单本身相关的FieldValue对象

public class FieldValue
{
    public string Id { get; set; }
    public string FieldId { get; set; }
    public string ValueAsJsonString { get; set; }
}
其他对象包括用户对象:

public class User
{
    public string Id { get; set; }
    public string Username { get; set; }
    public string GivenNames { get; set; }
    public string Surname { get; set; }
}
我希望能够执行一个查询,以查找由具有指定名称的用户完成的所有表单,或名称为X的字段具有值Y的所有表单,依此类推

我已经研究了文档中指定的索引的用法,但是当我实现以下示例时,文档中的实现抛出了NotSupportedException:

class FormTemplates_ByFieldAndName : AbstractIndexCreationTask<FormTemplate>
{
    public class Result
    {
        public string Name { get; set; }
        public IList<string> FieldNames { get; set; }
    }

    public FormTemplates_ByFieldAndName()
    {
        Map = FormTemplates => from FormTemplate in FormTemplates
                             select new
                             {
                                 Name = FormTemplate.Name,
                                 FieldNames = FormTemplate.FieldIds.Select(x => LoadDocument<FormField>(x).Name)
                             };
    }
}

// in code:
IList<FormTemplate> TestResults = session.Query<FormTemplates_ByFieldAndName.Result, FormTemplates_ByFieldAndName>()
                    .Where(x => x.Name == "TemplateName" || x.FieldNames.Contains("FieldName"))
                    .OfType<FormTemplate>()
                    .ToList();
class FormTemplates\u ByFieldAndName:AbstractIndexCreationTask
{
公开课成绩
{
公共字符串名称{get;set;}
公共IList字段名{get;set;}
}
public FormTemplates_ByFieldAndName()
{
Map=FormTemplates=>来自FormTemplates中的FormTemplate
选择新的
{
Name=FormTemplate.Name,
FieldNames=FormTemplate.FieldId.Select(x=>LoadDocument(x).Name)
};
}
}
//代码:
IList TestResults=session.Query()
.Where(x=>x.Name==“TemplateName”| | x.FieldName.Contains(“FieldName”))
第()类
.ToList();
据我所知,这是正确实现的,但是我看到一个建议,用.Any实现替换.Contains。代替这一点,我一直在用一种不同的方法进行试验,方法是应用连续的.Where参数。像这样:

 var pre = session.Query<FormTemplates_ByFieldAndName.Result, FormTemplates_ByFieldAndName>();
 var pr2 = pre.Where(x => x.Name == "TypeTest25");

 List<FormTemplate> TestResults = pr2
     .Where(x => x.FieldNames.Any(a => a == "field25"))
     .OfType<FormTemplate>()
     .OrderByScoreDescending()
     .ToList();
var pre=session.Query();
var pr2=pre.Where(x=>x.Name==“TypeTest25”);
列出TestResults=pr2
.Where(x=>x.FieldNames.Any(a=>a==“field25”))
第()类
.OrderByScoreDescending()
.ToList();
通过基于预先指定的格式提供的字符串应用连续过滤器,修改系统以更面向工厂的方式执行


这是我实现此功能的方式吗?如果不是,我应该改变什么?特别是,如果我要继续使用索引选项,我将如何通过FormTemplates将此技术应用于表单和FormFields之间的嵌套关系。

您似乎试图以一种主要是关系的方式来实现这一点,但您不必这样做

与其尝试拥有一组独立的文档,每个文档都有部分数据,不如将其全部存储在单个文档中

public class Form
{
    public string Id { get; set; }
    public string Name { get; set; }
    public IList<FieldValue> FieldValues { get; set; }
    public string UserId { get; set; } // the user who completed the form.
    public string FormTemplateId { get; set; }
}

public class FieldValue
{
    public string Id { get; set; }
    // can store the value directly!
    //public string ValueAsJsonString { get; set; }
    public object Value {get; set; }
}
这是一种更自然的建模方式。 此时,您可以使用RavenDB的动态数据索引功能,请参见此处的文档:


哦,谢谢!我编辑了上面的示例,以更准确地反映fieldValue的性质。是否可以让我的索引也表示FormField和FieldValue对象之间的关系?也就是说,我希望能够有一个查询,在那里我能够找到所有表单,其中有一个formField X和一个与之关联的FormValue Y。到目前为止,我可以做一个或另一个都没有特定的功能。是的,你当然可以这样做。这就是动态字段发挥作用的地方。如何格式化lucene语法查询以访问这些动态字段?请参见答案中的查询,这是:IList results=session.Advanced.DocumentQuery()。WhereEquals(“MyDynamicField”,“Red”).ToList();
 var pre = session.Query<FormTemplates_ByFieldAndName.Result, FormTemplates_ByFieldAndName>();
 var pr2 = pre.Where(x => x.Name == "TypeTest25");

 List<FormTemplate> TestResults = pr2
     .Where(x => x.FieldNames.Any(a => a == "field25"))
     .OfType<FormTemplate>()
     .OrderByScoreDescending()
     .ToList();
public class Form
{
    public string Id { get; set; }
    public string Name { get; set; }
    public IList<FieldValue> FieldValues { get; set; }
    public string UserId { get; set; } // the user who completed the form.
    public string FormTemplateId { get; set; }
}

public class FieldValue
{
    public string Id { get; set; }
    // can store the value directly!
    //public string ValueAsJsonString { get; set; }
    public object Value {get; set; }
}
{
  "Id": "forms/1234",
  "Name": "Tom",
  "FieldValues": [
   {
      "Id": "FromValues/SchoolDistrictName",
      "Value": "ABi195"
    }
  ],
  "UserId": "users/tom",
  "FormTemplateId": "FromTemplate/1234"
}