【问题标题】:RavenDB index for 2 nested many-to-many relationship entities用于 2 个嵌套多对多关系实体的 RavenDB 索引
【发布时间】:2014-01-28 19:11:45
【问题描述】:

我在 RavenDB 中有以下实体集合:

public class Provider
{
    public string ProviderId {get; set;}
    public string ProviderName {get; set;}
    public string[] CategoryIds{get; set;}
}

public class Category
{
    public string CategoryId {get; set;}
    public string CategoryName {get; set;}
    public string[] ServiceIds {get; set;}
}

public class Service
{
    public string ServiceId {get; set;}
    public string ServiceName {get; set;}
    public string ServiceCode {get; set;}
}

这是一个 2 级的多对多关系。现在我需要创建索引来平整结构,以便搜索结果。

  1. 可以提供特定服务的搜索提供商
  2. 搜索包含特定服务的类别
  3. 提供商可以提供的搜索服务

我的索引结果模型应该是这样的:

public class ProviderCategoryService
{
    public string ProviderId {get; set;}
    public string ProviderName {get; set;}
    public string CategoryId {get; set;}
    public string CategoryName {get; set;}
    public string ServiceId {get; set;}
    public string ServiceName {get; set;}
    public string ServiceCode {get; set;}
}

我可以只在一个索引中实现上述功能还是需要创建多个索引?

*编辑:按多个字段使用分组,然后使用转换器。 *

我想出了这个索引。

public class ProviderCategoryServiceSearch:AbstractMultiMapIndexCreationTask<IndexResult>
{
    public ProviderCategoryServiceSearch()
    {
        AddMap<Provider>(providers => from p in providers from c in p.CategoryIds
            select new {
                ProviderId = p.ProviderId,
                ProviderName = p.ProviderName,
                CategoryId = c,           
                CategoryName = (string)null,
                ServiceId = (string)null,
                ServiceName = (string)null,
                ServiceCode = (string)null,
        });

        AddMap<Category>(categories => from c in categories from s in ServiceIds
            select new {
                ProviderId = (string)null,
                ProviderName = (string)null,
                CategoryId = c.CategoryId,           
                CategoryName = c.CategoryName,
                ServiceId = s,
                ServiceName = (string)null,
                ServiceCode = (string)null,
        });

        Reduce = results => from r in results
            group r by new {r.CategoryId, r.ServiceId} into g
            from record in g
            select new {
                ProviderId = g.Select(x => x.ProviderId).FirstOrDefault(x => x != null),
                ProviderName = g.Select(x => x.ProviderName).FirstOrDefault(x => x != null),
                CategoryId = g.Key.CategoryId,           
                CategoryName = g.Select(x => x.CategoryName).FirstOrDefault(x => x != null),
                ServiceId = g.Key.ServiceId,
                ServiceName = (string)null,
                ServiceCode = (string)null,
             };
    }


    public class MyTransformer : AbstractTransformerCreationTask<IndexResult>
    {
        public MyTransformer()
        {
             TransformResults = results => from r in results
                 let s= LoadDocument<Service>(r.ServiceId)
                 select new {
                     ProviderId = r.ProviderId,
                    ProviderName = r.ProviderName,
                    CategoryId = r.CategoryId,           
                    CategoryName = r.CategoryName,
                    ServiceId = r.ServiceId,
                    ServiceName = s.ServiceName,
                    ServiceCode = s.ServiceCode,
            };
        }
    }
}

这个实现有什么问题吗?

【问题讨论】:

    标签: c# linq mapreduce ravendb


    【解决方案1】:

    这种方法没问题。这是 Raven 1.0 中的工作方式。然而,自从在 2.0 和 2.5 中引入 LoadDocument 以来,它已经变得几乎没有必要了。阅读更多here。当您可以将相关文档加载到索引映射中时,您会发现不需要 multimap 或 reduce。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-31
      • 1970-01-01
      • 2015-07-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多