基于非标识属性的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没有一个简单的方法来做到这一点。

你可以通过变换来把它弄出来。唯一的问题是,您将跳过结果集中的项,因此请确保您知道如何处理这些项。

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

请参见此处的完整单元测试。

还有另一种方法,但我还没有测试过。这将使用Indexed Properties Bundle进行第一次传递,然后为第二次传递映射这些结果。我正在试验这一般,如果它的工作,我将更新这个答案与结果。

相关内容

  • 没有找到相关文章

最新更新