2

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ため、それらは交差する可能性があります。

のプロパティが指定された値と等しい場所でEntityAタグが交差するすべてのものを取得するにはどうすればよいですか?EntityBNameEntityB

4

1 に答える 1

2

まあ、これは難しいものです。それを正しく行うには、2つのレベルの削減が必要になります。1つは結果を展開するタグによるもので、もう1つは折りたたむためのIDによるものです。レイヴンにはこれを行う簡単な方法がありません。

トランスフォームを使用して、それを偽造することができます。唯一の問題は、結果セットの項目をスキップすることです。そのため、それらの処理方法を知っていることを確認してください。

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

こちらの完全な単体テストも参照してください。

別のアプローチがありますが、私はまだそれをテストしていません。これは、インデックス付きプロパティバンドルを使用して最初のパスを実行し、次にそれらの結果を2番目のパスにマップすることです。私はこれを一般的に実験しており、うまくいったら、この回答を結果で更新します。

于 2013-01-14T20:04:19.420 に答える