用于RavenDB的多个Contains / Any的Linq查询

我有一个包含“标签”列表的文档类。 就像是:

class Item { string Name { get; set; } List Tags {get; set;} } 

现在我想为RavenDB创建一个查询,它将所有按标签列表过滤的项目交给我。 使用entity framework时,我设法通过以下方式执行此操作:

 var query = GetQueryable(); foreach (var tag in tags) { query = query.Where(i => i.Tags.Contains(tag)); } 

但是,这似乎不适用于RavenDB,很可能因为不支持Contains ..我也尝试使用Any重写它,( Where(i => i.Tags.Any(t=>t == tag)) )但这给了我一个奇怪的例外:

 Unable to cast object of type 'System.Linq.Expressions.PrimitiveParameterExpression`1[System.String]' to type 'System.Linq.Expressions.MemberExpression 

有什么好主意吗? 我这样做完全错了吗?

确实还没有支持包含(也许它应该是,但这完全是另一回事 – 我们只是在它要求时才真正添加对各种运营商的支持)

至于针对Any的多个查询,我假设您正在尝试执行动态数据,并且您希望实现类似的function

 "X OR Y OR Z" 

这是一个棘手的问题,默认情况下LINQ提供程序将使用AND聚合这些多个WHERE子句,因此您的示例看起来像

 "X AND Y AND Z" 

显然绝不会是这种情况。

这个问题的最佳选择是下拉到Lucene查询(至少目前为止)并执行以下操作:

 var results = s.Advanced.LuceneQuery() .Where(string.Format("Tags,:({0})", string.Join(" OR ", tags))); 

合理?

上面的查询看起来像

 "Tags,:(X OR Y OR Z)" 

注意:“标签”告知RavenDB标签是一个数组

好的,[编辑]!

获得实际需要的最简单方法是沿着这些方向做点什么

  new IndexDefinition() { Map = docs => from doc in docs select new { Tags = doc.Tags }, Indexes = {{ x => x.Tags, FieldIndexing.Analyzed }} }.ToIndexDefinition(store.Conventions)); 

然后要查询你的ands,你可以这样做:

  var results = s.Advanced.LuceneQuery() .Where(string.Format("Tags:({0})", string.Join(" AND ", tags))); 

现在,要注意的事情

  Tags = doc.Tags 

将整个数组序列化为一个巨大的blob,因为它只是适用于此示例的字符串。

我正在寻找更好的方式来表达这一点,我们不太可能想出一个LINQ-ish的方法来做到这一点,因为它并没有真正映射得很好 – 但它一个可行的答案:)

我想我至少能够这样做

  Map = docs => from doc in docs select new { Tags = String.Join(" ", doc.Tags) }, 

(这不会起作用所以不要尝试),但是对于你想要实现的目标更明确一点。