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

实时投影中加载的产品为空,我不知道如何使用 ProductType 进行过滤。

任何帮助表示赞赏。

4

1 回答 1

1

根据评论中的讨论,我对这个问题有了更好的理解。具体来说,嵌入在类中,Product是其他产品的基类。因此,您不能使用我描述的方法(请参阅编辑),因为在索引.OfferProductOffer

解决方案是依赖于您的基类将使用$type属性序列化的事实。这是由 Json.Net 完成的,因为您存储的是派生类型的类。序列化Offer文档如下所示:

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

为了绝对确保$type永远存在,将Product类标记为,abstract以便所有实际产品都必须是派生类。

因此,当您构建索引图时,您需要访问此字段。您可以使用以下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 回答