c# - 非标识符属性上的 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; }
    public string[] Tags { get; set; }
}

唯一共享的是 Tags 集合:EntityA 的标签可能存在于 EntityB 中,因此它们可能相交。

如何检索每个 EntityAEntityB 有交叉标签,其中 EntityBName 属性是等于给定值?

最佳答案

嗯,这是一个困难的问题。要做到这一点,您需要两个级别的减少 - 一个通过标签扩展您的结果,另一个通过 id 将其折叠回去。 Raven 没有简单的方法来做到这一点。

您可以使用变换伪造它。唯一的问题是您将拥有 skipped items在你的结果集中,所以确保你知道 how to deal with those .

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

另请参阅完整的单元测试 here .

还有另一种方法,但我还没有测试过。那将是使用 Indexed Properties Bundle进行第一遍,然后将这些结果映射到第二遍。我正在对此进行总体试验,如果可行,我会用结果更新此答案。

关于c# - 非标识符属性上的 RavenDB 跨实体查询匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14322959/

相关文章:

c# - 将动态表达式传递给代码优先 EF 存储库中的排序依据

C#:在泛型类中添加条件泛型方法(不同的泛型限制)

java - 获取权限被拒绝(公钥)。在AWS上启动hadoop集群时

c# - Json.net 上的反序列化更改属性类型和名称

c# - Caliburn Micro 将非通用参数传递给新的 ViewModel

c# - Web.config 保存问题

c# - 通用存储库 - IRepository<T> 或 IRepository

hadoop - 为什么我没有在 hadoop 的输出文件中写入输出?

java - Hadoop DistributedCache 对象在作业期间更改

c# - DataGridViewColumn.Frozen 单声道 2.10