我正在使用RavenDB build 371,我有以下型号:
class Product {
public string Id { get; set; }
public ProductSpec[] Specs { get; set; }
}
class ProductSpec {
public string Name { get; set; }
public string Value { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
我希望能够查询具有一组规格的产品.查询单个规范时:
session.Query<Product>()
.Where(product => product.Specs.Any(spec => spec.Name == "Color" && spec.Value == "Red"))
.ToList();
Run Code Online (Sandbox Code Playgroud)
返回预期结果,但是当添加其他规范谓词时:
session.Query<Product>()
.Where(product => product.Specs.Any(spec => spec.Name == "Color" && spec.Value == "Red"))
.Where(product => product.Specs.Any(spec => spec.Name == "Country" && spec.Value == "US"))
.ToList();
Run Code Online (Sandbox Code Playgroud)
即使第一个查询返回的结果包含规格名称为"Country"且规格值为"US"的产品,也不会返回任何结果.使用LuceneQuery方法时会观察到相同的结果.这似乎与此讨论类似,但我无法实施建议的解决方案.具体来说,在创建建议的索引后,我不知道如何查询它.
如何在RavenDB中支持这种类型的查询?
编辑
我仍然无法查询复合类型集合上的多个值.相反,我更改了模型,以便spec/value组合是一个连接的字符串,这样specs集合就是一个字符串数组.这可以通过多个值查询:
class Product {
public string Id { get; set; }
public int CategoryId { get; set; }
public string[] Specs { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
作为参考,当使用MongoDB及其多键索引功能时,原始模型和查询起作用.MongoDB的一个非常令人惊讶的问题是,对于索引查询,count()操作很慢.这种类型的查询对于分页是必不可少的,虽然可以缓存计数,但我想要一个解决方案,它提供了开箱即用的功能.此外,我的另一个要求是能够为任意产品集合聚合规范组(例如,获取给定类别中产品的所有规范/值组合的集合).在MongoDB中,这可以使用他们的MapReduce功能来实现,但是MapReduce操作的结果是静态的,并且必须在源数据更改时手动更新,而RavenDB在后台自动更新MapReduce索引.因此,即使在RavenDB中声明MapReduce索引比在MongoDB IMO中更加繁琐,自动后台更新也远远超过了长镜头的缺点.我将关注CouchDB,因为他们的视图也会自动更新,但看起来它们是按需更新的,而不是在后台自动更新,不确定这是否会成为问题.
我对模型进行了一些更改,并且能够使用 AbstractIndexCreationTask 中的 Project 方法获得所需的结果。这是(简化的)数据模型:
public class Product
{
public string Id { get; set; }
public int CategoryId { get; set; }
public int TotalSold { get; set; }
public Dictionary<string, string> Specs { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
这是索引定义:
public class Products_ByCategoryIdAndSpecs_SortByTotalSold : AbstractIndexCreationTask<Product>
{
public Products_ByCategoryIdAndSpecs_SortByTotalSold()
{
this.Map = products => from product in products
select new
{
product.CategoryId,
_ = Project(product.Specs, spec => new Field("Spec_" + spec.Key, spec.Value, Field.Store.NO, Field.Index.ANALYZED)),
product.TotalSold
};
}
}
Run Code Online (Sandbox Code Playgroud)
然后我可以像这样查询:
var results = session.Advanced.LuceneQuery<Product, Products_ByCategoryIdAndSpecs_SortByTotalSold>()
.WhereEquals("CategoryId", 15920)
.AndAlso().WhereEquals("Spec_Class", "3A")
.AndAlso().WhereEquals("Spec_Finish", "Plain")
.OrderBy("-TotalSold")
.ToList();
Run Code Online (Sandbox Code Playgroud)
这将返回类别“15920”中的产品,这些产品的“Class”规格值为“3A”,“Finish”规格值为“Plain”,按销售总量降序排列。
关键是使用Project基本上为每个规范名称-值对在 Lucene 文档中创建字段的方法。
| 归档时间: |
|
| 查看次数: |
3119 次 |
| 最近记录: |