Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 基于非标识符属性的RavenDB跨实体查询匹配_C#_Linq_Mapreduce_Ravendb - Fatal编程技术网

C# 基于非标识符属性的RavenDB跨实体查询匹配

C# 基于非标识符属性的RavenDB跨实体查询匹配,c#,linq,mapreduce,ravendb,C#,Linq,Mapreduce,Ravendb,我在RavenDB中拥有以下实体集合: public class EntityA { public string Id { get; set; } public string Name { get; set; } public string[] Tags { get; set; } } public class EntityB { public string Id { get; set; } public string Name { get; set;

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

public class EntityA
{
    public string Id { get; set; }
    public string Name { get; set; }
    public string[] Tags { get; set; }
}

public class EntityB
{
    public string Id { get; set; }
    public string Name { get; set; }
    public string[] Tags { get; set; }
}
唯一共享的是
标记
集合:一个
实体a
的标记可能存在于
实体b
中,因此它们可能相交


如果
EntityB
Name
属性等于给定值,如何检索每个
EntityA
EntityB
具有交叉标记的
EntityA
。要正确地执行此操作,您需要两个级别的缩减—一个是通过标签展开结果,另一个是通过id将结果折叠回来。瑞文没有一个简单的方法来做到这一点

您可以通过使用变换来伪造它。唯一的问题是,你的结果集中会有,所以确保你知道

公共类TestIndex:AbstractMultiMapIndexCreationTask
{
公开课成绩
{
公共字符串[]id{get;set;}
公共字符串名称{get;set;}
公共字符串标记{get;set;}
}
公共测试索引()
{
AddMap(实体=>来自实体中的
从a.Tags.DefaultIfEmpty(“389;”)中的标记开始
选择新的
{
Ids=new[]{a.Id},
Name=(字符串)null,
标签=标签
});
AddMap(实体=>来自实体中的b
从b.标签中的标签
选择新的
{
Ids=新字符串[0],
b、 名字,
标签=标签
});
Reduce=results=>from result in results
按result.Tag对结果进行分组
进入g
选择新的
{
Ids=g.SelectMany(x=>x.Ids),
g、 第一个(x=>x.Name!=null).Name,
Tag=g.键
};
TransformResults=(数据库、结果)=>
结果。选择多个(x=>x.Ids)
.Distinct()
.Select(x=>database.Load(x));
}
}
另请参见完整单元测试


还有另一种方法,但我还没有测试过。这将是使用进行第一次传递,然后映射第二次传递的结果。一般来说,我正在试验这个方法,如果有效的话,我会用结果更新这个答案。

你的标签表明你一直在寻找正确的地方-你已经有了什么索引?目前我对多重地图索引、变换、包含和活体投影有着深入的了解-我无法理解这个问题。解决办法是去数据库两次,但我不想去。超级马特!干得好。要添加,在查询索引时还将应用可选的“where”子句:我需要某种“外部联接”来工作,这样,如果EntityA有0/null标记,它仍将在结果集中返回。出于这个原因,我将研究索引属性方法,以防跳过的结果问题可能会干扰。谢谢你是说你想要每个
实体a
?或者您想包括没有标记的
EntityA
s吗?我想包括没有标记的
EntityA
s。我更新了示例,以显示您可以通过使用
DefaultIfEmpty
分配占位符项来实现这一点。(只要该值不为null,它就不重要。)还更新了gist上的单元测试,您应该查看它,因为它显示了排序结果如何在这种方法中出现问题。
public class TestIndex : AbstractMultiMapIndexCreationTask<TestIndex.Result>
{
    public class Result
    {
        public string[] Ids { get; set; }
        public string Name { get; set; }
        public string Tag { get; set; }
    }

    public TestIndex()
    {
        AddMap<EntityA>(entities => from a in entities
                                    from tag in a.Tags.DefaultIfEmpty("_")
                                    select new
                                        {
                                            Ids = new[] { a.Id },
                                            Name = (string) null,
                                            Tag = tag
                                        });

        AddMap<EntityB>(entities => from b in entities
                                    from tag in b.Tags
                                    select new
                                        {
                                            Ids = new string[0],
                                            b.Name,
                                            Tag = tag
                                        });

        Reduce = results => from result in results
                            group result by result.Tag
                            into g
                            select new
                                {
                                    Ids = g.SelectMany(x => x.Ids),
                                    g.First(x => x.Name != null).Name,
                                    Tag = g.Key
                                };

        TransformResults = (database, results) => 
                           results.SelectMany(x => x.Ids)
                                  .Distinct()
                                  .Select(x => database.Load<EntityA>(x));
    }
}