我有一种情况,我希望通过两个字段进行查询,我认为这很简单,但事实证明这比我想象的要困难得多。
这是对被查询文件的粗略看法......
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;没有定义。当我非常明确地定义它时,我真的很困惑为什么会说这个。
答案 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对象的高级查询时