基于属性的索引提示改变了我的结果
Attribute based index hints change my results
我有这个查询,自从我第一次使用它以来就没有改变过:
ISearchResponse<Series> response = await IndexManager.GetClient()
.SearchAsync<Series>(r => r
.Filter(f => f.Term<Role>(t => t.ReleasableTo.First(), Role.Visitor))
.SortDescending(ser => ser.EndDate)
.Size(1));
我的 IndexManager.GetClient()
只负责设置我与 ElasticSearch 的连接,并确保正确构建索引。其余代码获取最新的文章系列,可发布给一般public.
在 IndexManager
中,我设置了显式索引映射,当我这样做时,我每次都从查询中获得结果。代码如下所示:
client.Map<Series>(m => m.Dynamic(DynamicMappingOption.Allow)
.DynamicTemplates(t => t
.Add(a => a.Name("releasableTo").Match("*releasableTo").MatchMappingType("string").Mapping(map => map.String(s => s.Index(FieldIndexOption.NotAnalyzed))))
.Add(a => a.Name("id").Match("*id").MatchMappingType("string").Mapping(map => map.String(s => s.Index(FieldIndexOption.NotAnalyzed))))
.Add(a => a.Name("services").Match("*amPm").MatchMappingType("string").Mapping(map => map.String(s => s.Index(FieldIndexOption.NotAnalyzed)))
.Match("*dayOfWeek").MatchMappingType("string").Mapping(map => map.String(s => s.Index(FieldIndexOption.NotAnalyzed))))
.Add(a => a.Name("urls").Match("*Url").MatchMappingType("string").Mapping(map => map.String(s => s.Index(FieldIndexOption.NotAnalyzed))))
));
虽然一切都很好,但对我们存储的每种类型都这样做并不能很好地扩展。所以我有意识地决定使用属性并以这种方式映射它:
// In IndexManager
client.Map<T>(m => m.MapFromAttributes());
// In the type definition
class Series
{
// ....
[DataMember]
[ElasticProperty(Index = FieldIndexOption.NotAnalyzed, Store = true)]
public HashSet<Role> ReleasableTo { get; set; }
// ....
}
我一这样做,就再也得不到结果了。当我在 Kibana 中查看我的索引时,我发现我的 'releasableTo' 字段没有被分析并且被索引了。但是我写的查询不再有效。如果我删除过滤器子句,我会得到结果,但我确实需要它才能工作。
我错过了什么?如何让我的查询再次生效?
提供索引提示的 ElasticSearch 属性似乎不知道如何处理 enum
s。
原来是Role
类型是枚举的问题。 client.Map<Series>(m => m.MapFromAttributes())
调用跳过了 属性。在 运行 时,它将 属性 动态映射到字符串。
// In the type definition
class Series
{
// ....
[DataMember]
[ElasticProperty(Index = FieldIndexOption.NotAnalyzed, Store = true)]
public HashSet<Role> ReleasableTo { get; set; }
// ....
}
为了正确索引该字段,我必须在 ElasticProperty
属性中明确设置它的类型。将代码更改为:
// In the type definition
class Series
{
// ....
[DataMember]
[ElasticProperty(Index = FieldIndexOption.NotAnalyzed, Type = FieldType.String, Store = true)]
public HashSet<Role> ReleasableTo { get; set; }
// ....
}
使我的查询再次起作用。这个故事的寓意是,除非它是原始类型,否则在设置字段类型时要明确。
我有这个查询,自从我第一次使用它以来就没有改变过:
ISearchResponse<Series> response = await IndexManager.GetClient()
.SearchAsync<Series>(r => r
.Filter(f => f.Term<Role>(t => t.ReleasableTo.First(), Role.Visitor))
.SortDescending(ser => ser.EndDate)
.Size(1));
我的 IndexManager.GetClient()
只负责设置我与 ElasticSearch 的连接,并确保正确构建索引。其余代码获取最新的文章系列,可发布给一般public.
在 IndexManager
中,我设置了显式索引映射,当我这样做时,我每次都从查询中获得结果。代码如下所示:
client.Map<Series>(m => m.Dynamic(DynamicMappingOption.Allow)
.DynamicTemplates(t => t
.Add(a => a.Name("releasableTo").Match("*releasableTo").MatchMappingType("string").Mapping(map => map.String(s => s.Index(FieldIndexOption.NotAnalyzed))))
.Add(a => a.Name("id").Match("*id").MatchMappingType("string").Mapping(map => map.String(s => s.Index(FieldIndexOption.NotAnalyzed))))
.Add(a => a.Name("services").Match("*amPm").MatchMappingType("string").Mapping(map => map.String(s => s.Index(FieldIndexOption.NotAnalyzed)))
.Match("*dayOfWeek").MatchMappingType("string").Mapping(map => map.String(s => s.Index(FieldIndexOption.NotAnalyzed))))
.Add(a => a.Name("urls").Match("*Url").MatchMappingType("string").Mapping(map => map.String(s => s.Index(FieldIndexOption.NotAnalyzed))))
));
虽然一切都很好,但对我们存储的每种类型都这样做并不能很好地扩展。所以我有意识地决定使用属性并以这种方式映射它:
// In IndexManager
client.Map<T>(m => m.MapFromAttributes());
// In the type definition
class Series
{
// ....
[DataMember]
[ElasticProperty(Index = FieldIndexOption.NotAnalyzed, Store = true)]
public HashSet<Role> ReleasableTo { get; set; }
// ....
}
我一这样做,就再也得不到结果了。当我在 Kibana 中查看我的索引时,我发现我的 'releasableTo' 字段没有被分析并且被索引了。但是我写的查询不再有效。如果我删除过滤器子句,我会得到结果,但我确实需要它才能工作。
我错过了什么?如何让我的查询再次生效?
提供索引提示的 ElasticSearch 属性似乎不知道如何处理 enum
s。
原来是Role
类型是枚举的问题。 client.Map<Series>(m => m.MapFromAttributes())
调用跳过了 属性。在 运行 时,它将 属性 动态映射到字符串。
// In the type definition
class Series
{
// ....
[DataMember]
[ElasticProperty(Index = FieldIndexOption.NotAnalyzed, Store = true)]
public HashSet<Role> ReleasableTo { get; set; }
// ....
}
为了正确索引该字段,我必须在 ElasticProperty
属性中明确设置它的类型。将代码更改为:
// In the type definition
class Series
{
// ....
[DataMember]
[ElasticProperty(Index = FieldIndexOption.NotAnalyzed, Type = FieldType.String, Store = true)]
public HashSet<Role> ReleasableTo { get; set; }
// ....
}
使我的查询再次起作用。这个故事的寓意是,除非它是原始类型,否则在设置字段类型时要明确。