2012-12-05 46 views
4

鉴于所有项目:查找那里的孩子集合不包含的项目

public class Order 
{ 
    public string Name {get;set;} 
    public List<LineItem> LineItems {get; set;} 
} 

public class LineItem 
{ 
    public string Product {get; set;} 
    public int Quantity {get; set;} 
} 

我试图找出如何构建一个查询,将返回所有的订单是有带有名为“Apple”的产品的LineItem

回答

4

我一直在想这个问题。它出现了几次。问题是Raven目前不处理.Any()或.All()查询。

这个特殊的例子足以简化问题,它让我思考了一条不同的路径。我相信有一个解决方案。它需要对一个静态指标Lucene的查询:

public class Orders_ByProduct : AbstractIndexCreationTask<Order> 
{ 
    public Orders_ByProduct() 
    { 
    Map = orders => from order in orders 
        select new 
        { 
         Product = order.LineItems.Select(x => x.Product) 
        }; 
    } 
} 

var ordersWithoutApple = session.Advanced 
           .LuceneQuery<Order, Orders_ByProduct>() 
           .Where("*:* AND -Product: Apple") 
+0

又见它使用相同的指数形式wizzardz的回答,但他想通了如何表达在简单的linq中查询。 –

+0

当人们想要在两个集合之间执行'.Except',或者'.Any &&!.Any'时,这也很有用。我想找到一个用户是一部分但不活跃的组,并且** Linq **我是:'.Where(g => g.AllUserIdsInGroup.Any(id => userId == id)&&! g.ActiveUserIdsInGroup.Any(id => userId == id))'因为!.Any而失败,但是这个** Lucene查询**工作:''AllUserIdsInGroup:234 AND -ActiveUserIdsInGroup:234“' –

2

,你可以做到这一点为您的查询创建索引

public class GetOrdersByProductIndex: AbstractIndexCreationTask<Order,GetOrdersByProductIndex.Result> 
{ 
    public class Result 
    { 
    public string Product {get; set;} 
    } 

    public GetOrdersByProductIndex() 
    { 
    Map = orders => from order in orders 
        select new 
        { 
         Product = order.LineItems.Select(x => x.Product) 
        }; 
    } 
} 

现在你可以使用这个指标,让您的订单。您的查询应该是这样的

using(IDocumentSession session = docStore.OpenSession()) 
{ 
    var orders = session.Query<GetOrdersByProductIndex.Result,GetOrdersByProductIndex> 
         .Where(x=>x.Product != "Apple") 
         .As<Order>() 
         .ToList() 
} 

请注意,默认情况下它只会返回128条记录(因为由ravendb设置的限制),如果你的查询结果有超过128分的记录,你应该使用Take(recordsNeeded)函数取数据。

+0

嗯,我觉得愚蠢 - linq翻译为“( - 产品:苹果和产品:*)”,这几乎是我写的lucene。我不能为我的生活弄清楚如何表达否定。一个简单的!=似乎工作得很好。谢谢! –

1

我们能够有一个明确的比较来解决RavenDB的缺乏支持!.Anyfalse,如:

orders.Where(x => x.LineItems.Any(y => y.Product == "Apple") == false) 
+0

做得很简单,做得很好 –

相关问题