1

わかりました、私はこれらのPOCOを持っています

public class Product
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Manufacturer { get; set; }
}

public class Offer
{
    public int Id { get; set; }
    public User Seller { get; set; }
    public Product Product { get; set; }
    public decimal Price { get; set; }
}

Productから派生したクラスがたくさんありますが、クラスOfferの製品プロパティはそれらのいずれかになります。

商品の最低価格のオファーを返す静的インデックスを定義し、商品タイプでフィルタリングしたいと思います。

ここまで来ました。

        Map = offers => offers.Select(x => new Offer { Product = x.Product, Price = x.Price });

        Reduce = results => from r in results
                            group r by r.Product into g
                            select new Offer { Product = g.Key , Price = g.Min(x => x.Price) };

これは機能し、最低価格を提供しますが、MapはProduct.Idのみを使用する必要があり、全体ではないと思います(方法がわかりません)。

そして、私がインデックスを照会するとき:

Session.Query<Offer>("BestOffersIndex").Where(offer => offer.Product is DerivedProduct)

Where条件を無視するだけです。

私がこれを行う場合:

        Map = offers => offers.Select(x => new OfferIndexResult { ProductType = MetadataFor(x.Product)["Raven-Entity-Name"].ToString(), ProductId = x.Product.Id, Price = x.Price });

        Reduce = results => from r in results
                            group r by r.ProductId into g
                            select new OfferIndexResult { ProductType = g.FirstOrDefault().ProductType, ProductId = g.Key, Price = g.Min(x => x.Price) };

        TransformResults = (database, offers) => from offer in offers
                                                 let product = database.Load<Product>(offer.ProductId.ToString())
                                                 select new Offer { Product = product, Price = offer.Price }; 

ライブプロジェクションに読み込まれた製品がnullであり、フィルタリングの目的でProductTypeを使用する方法がわかりません。

どんな助けでも大歓迎です。

4

1 に答える 1

1

コメントでの議論に基づいて、私は問題をよりよく理解しています。具体的には、Productがクラスに組み込まれておりOffer、他の製品の基本クラスです。Productしたがって、私が説明したアプローチを使用することはできません (編集を参照) Offer

$type解決策は、基本クラスが属性でシリアル化されるという事実に依存することです。派生型のクラスを格納しているため、これは Json.Net によって行われます。シリアル化されたOfferドキュメントは次のようになります。

{
  "SellerUserId": 1,
  "Product": {
    "$type": "YourNamespace.TheProductType, YourAssembly",
    "Id": 1,
    "Name": "product name",
    "Manufacturer": "manufacturer"
  },
  "Price": 10.0
}

が常に存在することを確実にするために、すべての実際の製品が派生クラスでなければならないように、クラスを$typeマークします。Productabstract

したがって、インデックス マップを作成するときは、このフィールドにアクセスする必要があります。AsDocument次の方法で取得できます。

Map = offers => from offer in offers
                select new
                {
                    Product = offer.Product,
                    offer.Price,
                    ProductType = AsDocument(offer.Product)["$type"]
                };

クエリに移動して製品タイプでフィルタリングする場合、次のように文字列の製品タイプを取得できます。

var productType = documentStore.Conventions.GetClrTypeName(typeof(ProductA));

ここに完全な単体テストをまとめて、この手法を使用して説明した目標を達成する方法を示します。

于 2013-01-17T01:54:38.043 に答える