两个嵌套的多对多关系实体的RavenDB索引

时间:2014-01-28 19:11:46

标签: c# linq mapreduce ravendb

我在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. 提供商可以提供的搜索服务
  4. 我的索引结果模型应该是这样的:

    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,
                };
            }
        }
    }
    

    此实施有任何问题吗?

1 个答案:

答案 0 :(得分:0)

这种方法还可以。这是在Raven 1.0中完成的事情。但是,自从2.0和2.5中引入LoadDocument以来,它几乎没有必要。阅读更多here。当您可以将相关文档加载到索引图中时,您会发现不需要multimap或reduce。