RavenDB:两个WHERE查询困难

时间:2013-12-27 18:56:30

标签: ravendb

我有一种情况,我希望通过两个字段进行查询,我认为这很简单,但事实证明这比我想象的要困难得多。

这是对被查询文件的粗略看法......

class Item {
   string Id { get; set; }
   string Name { get; set; }
   Origin Origin { get; set; }
}

class Origin {
   string Id { get; set; }
   string Name { get; set; }
}

当然还有其他领域。我只是列出相关的。所以我的索引看起来像这样。

public class Item__ByName : AbstractIndexCreationTask<Models.Items.Item, Item__ByName.Result> {

    public class Result {
        public string Id { get; set; }
        public string Name { get; set; }
        public string Origin { get; set; }
    }

    public Item__ByName() {
        Map = items => from item in items
                       select new Result {
                           Id = item.Id,
                           Name = item.Name,
                           Origin = item.Origin.Name
                       };

        Index(i => i.Name, FieldIndexing.Analyzed);
        Index(i => i.Origin, FieldIndexing.Analyzed);
    }
}

然后我尝试像这样查询......

var results = RavenSession
    .Query<Models.Items.Item, Indexes.Item__ByName>()
    .Where(n => n.Name == name)
    .Where(n => n.Origin.Name == origin)
    .ToList();

但它一直告诉我&#34; Origin_Name&#34;没有定义。当我非常明确地定义它时,我真的很困惑为什么会说这个。

2 个答案:

答案 0 :(得分:2)

有几件事:

  • 无法嵌套索引条目名称。即使文档具有结构,索引也是平的。为了弥补这一点,Raven使用了用下划线替换句点的惯例。因此,在索引定义中,您必须将字段Origin_Name命名为匹配。

    Origin_Name = item.Origin.Name
    
  • 几乎不需要在索引图中包含Id。它在幕后处理不同,因此默认包含它。

  • 在这种情况下,您不需要Result类,因为您没有存储这些字段或在map / reduce中使用它们。

  • 如果您打算进行部分匹配或搜索,那么分析字段就可以了。如果您只进行整个字符串匹配,则不应分析字段。

  • 您应该将Where个查询合并到一个子句中:

    .Where(n => n.Name == name && n.Origin.Name == origin)
    

    或者,您可以使用Intersection Queries功能:

    .Where(n => n.Name == name)
    .Intersect()
    .Where(n => n.Origin.Name == origin)
    
  • 这个特殊的查询很简单,如果你想要你可以省略静态索引,Raven会自动为你创建一个。

答案 1 :(得分:0)

你也可以在两个地方之间使用.And()和.Or(),特别是当你使用LuceneQuery对象的高级查询时