2

Nancy と RavenDB を使用してフォト ギャラリーを構築しています。次のようなモデル クラスがあります。

[JsonObject(IsReference=true)]
public class Album
{
    public Album()
    {
        this.Photos = new List<Photo>();
        this.Tags = new List<String>();
    }

    public String Id {get; set;}
    public String Name {get; set;}
    public String Path {get; set;}
    public DateTime ModifiedDate{get; set;}
    public IList<String> Tags {get; set;}
    public IList<Photo> Photos {get; set;}

}

    public class Photo
{
    public String Id {get; set;}
    public String Name {get; set;}
    public String Path {get; set;}
    public IList<String> Tags {get; set;}
    public Album Album {get; set;}
    public DateTime ModifiedDate{get; set;}
    public bool IsPrivate{get; set;}
}

そして、マップの私の試みは、写真 - >タグのインデックスを減らします:

   public class TaggedPhotosIndex:AbstractIndexCreationTask<Album, TaggedPhotos>
    {
        public TaggedPhotosIndex()
        {
            Map = albums =>
                from a in albums
                from p in a.Photos
                from t in p.Tags
                select new TaggedPhotos
                {
                    Tag = t,
                    PhotoIds = new List<String> {p.Id}
                };
            Reduce = results => 
                from result in results
                group result by result.Tag into agg
                select new TaggedPhotos
                {
                    Tag = agg.Key,
                    PhotoIds = agg.SelectMany(a => a.PhotoIds).ToList()
                };
        }
    }

    public class TaggedPhotos
    {
        public String Tag {get; set;}
        public IList<String> PhotoIds {get; set;}
    }

これが私が達成したいことです:

タグの配列を指定して、一致するタグが少なくとも 1 つあるすべての Photo オブジェクトを取得したいと考えています。

RavenDB は、クエリで SelectMany を許可しておらず、アイデアがありません。

解決策を見つけました (クライアント api を使用して ravendb の selectmany にLuceneQuery @ Workaround を使用) が、他の代替手段を楽しみにしています。

4

2 に答える 2

4

ドキュメント構造には、クエリを困難にするいくつかの問題があります。

  • クエリは、ドキュメント全体を返すように設計されています。ドキュメントから部分的な結果を求めています。これは可能ですが、すべてのフィールドをインデックスに保存し、そこから結果を投影する場合に限ります。RavenDB の強力な機能の 1 つであるドキュメント ストアの ACID 保証を放棄します。

  • Photoback からの参照があり、それを回避するようAlbumに設定している場合を除いて、通常は埋め込まれ、循環参照が発生します。[JsonObject(IsReference=true)]これは、単一のドキュメント内の基本的なシリアル化には機能する可能性がありますが、投影されたインデックス値からドキュメント全体を参照する場合には意味がありません。独自の「鶏と卵」の問題を設定しました。

  • この問題のドメインに期待される基本的な機能がまだありません。具体的には、アルバム全体を読み込まなくても 1 枚の写真を読み込むことができる必要があります。

写真を独自のドキュメントに入れることを強くお勧めします。次に、より単純なインデックスを作成し、循環参照を回避できます。DDD用語では、 と は両方とも集約PhotoですAlbum。そして、DDD 集約 == RavenDB ドキュメント。現在、集合体ではないエンティティとして写真をモデル化していますが、集合体に対してのみ行う操作 (検索など) を求めています。

「これらのタグのいずれかでタグ付けされた写真を含むすべてのアルバムをください」というだけの質問であれば、問題ありません。しかし、あなたはアルバムを求めているのではなく、写真を求めています。

そのようにモデル化したと仮定すると、ブレットの答えは近いですが、無関係なものがいくつかあります。完全な実装を示す単体テストを次に示します。元の質問に直接対処していないため、gist に投稿します。 https://gist.github.com/4499724

于 2013-01-10T05:42:20.397 に答える
1

これにはしばらく時間がかかりましたが、以下のソリューションが機能していることを確認しました。

まず、以下に示すように、インデックスとインデックスの結果を変更します。

 public class TaggedPhotosIndex:AbstractIndexCreationTask<Photo, TaggedPhotos>
    {
        public TaggedPhotosIndex()
        {
            Map = photos =>                
                from p in Photos
                from t in p.Tags
                select new TaggedPhotos
                {
                    Tag = t,
                    PhotoId = p.Id
                };
        }
    }

    public class TaggedPhotos
    {
        public string Tag {get; set;}
        public string PhotoId {get; set;}
    }

インデックスが作成されたので、これに対してクエリを実行して写真を取得する方法を次に示します。

var tagsToSearch = new List<string>(){"test1", "test2", "test3"};

var photoIds = documentSession.Query<TaggedPhotos, TaggedPhotoIndex>()
                               .Customize(x => x.Include<Photo>(p => p.Id))
                               .Where(x => x.Tag.In(tagsToSearch))
                               .Select(x => x.PhotoId)
                               .Distinct()
                               .ToArray();

// This doesn't actually make a second call as the photos are already loaded
// in the document session
var photos = documentSession.Load<Photo>(photoIds);

要件に基づく

これが私が達成したいことです:

タグの配列を指定して、一致するタグが少なくとも 1 つあるすべての Photo オブジェクトを取得したいと考えています。

アルバムが本当にすべてにどのように結びついているかわかりませんでした

于 2013-01-09T22:51:24.883 に答える