Querying a child collection by multiple values in RavenDB

眉间皱痕 提交于 2019-11-30 14:33:46
Stephan Ryer

I have tried different things, and could not make it work either. The specific query you are trying to execute is resolved to this Lucene query by RavenDB (in version 426):

"{(Name:Color AND Value:Red) AND (Name:Country AND Value:US)}" which explains why you get no result.

After googling on the subject, I found this post: Lucene Query Syntax

Different workarounds are suggested among the answers. Hope this will help. Im rather curious myself though, if this really isn't possible.

As per build 717 you can do this using the new .Intersect() feature that has been done by Matt Warren. Take a look here: http://issues.hibernatingrhinos.com/issue/RavenDB-51

I've changed the model a bit and was able to achieve the desired result using the Project method in AbstractIndexCreationTask. This is the (simplified) data model:

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

This is the index definition:

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

Then I can query like so:

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

This will return the products in category "15920" which have a "Class" spec value of "3A" and a "Finish" spec value of "Plain" sorted in descending order by the total units sold.

The key was using the Project method which basically creates fields in the Lucene document for each spec name-value pair.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!