,所以我成功地创建了"软件包"对象的索引,直接的文本查询正常工作。
我很想知道/如何使用部分填充的对象(类型"软件包")作为我搜索的标准?
软件包看起来像:
var packages = new List<Package> {
new Package {
Name = "Maverick",
TargetBusiness = new Business {
Industry = "Retail",
BusinessType = BusinessType.Product,
LocationType = LocationType.Store
},
Description = "Standard package for retail shops"
},
new Package {
Name = "Goose",
TargetBusiness = new Business {
Industry = "Retail",
BusinessType = BusinessType.Product,
LocationType = LocationType.Online
},
Description = "Standard package for ecommerce shops"
},
new Package {
Name = "Viper",
TargetBusiness = new Business {
Industry = "Advertising",
BusinessType = BusinessType.Service,
LocationType = LocationType.Office
},
Description = "Standard package test retail"
}
}
查询当前看起来像:
var result = client.Search<Package>(x => x.Query(q => q.QueryString(qs => qs.Query("q=retail"))));
但是我喜欢拥有类似的东西:
var result = client.Search<Package>(x => x.Query(q => q.Object(new Package{...etc ...})));
我希望我有意义:D预先感谢
var result = client.Search<Package>(x => x.Query(q => q.Object(new Package{...etc ...})));
永远无法工作,因为巢无法推断对象上每个属性的查询类型(即术语,前缀,通配符,query_string等)。
在您的示例中,q=retail
仅有效,因为elasticsearch
会将查询分解为q OR retail
。您可以使用常规Lucene语法(即targetBusiness.industry:retail
)定位字段。
在elasticsearch中,如果您的Querystring不绑定到字段,则默认情况下将在_all
字段中搜索,该搜索将为对象的所有属性提供所有术语。这就是为什么如果您确实有很多数据关闭_all
支持通常是一个很好的主意。
nest当前没有这样的功能,可以将其部分填充的对象并将其转换为Elasticsearch query_string
查询。
说这是您的查询:
client.Search<Package>(s=>s
.From(0)
.Size(10)
.Filter(f=>
f.Term(p=>p.TargetBusiness.Industry, "Advertising")
&& f.Exists(p=>p.Name)
)
.Query(q=>
q.QueryString(qs=>qs
.Query("ecommerce")
.Operator(Operator.and)
)
)
)
在上面的示例中,您必须创建自己的方法,以根据您的软件包在查询字符串查询中搜索所有术语。
即
public string MyPackageQueryString(Package package)
{
var myTerms = List<string>();
myTerms.Add(package.Name);
if (package.TargetBusiness != null)
{
myTerms.Add(package.Industry)
....
}
...
return string.Join(" ", myTerms.Where(t=>!string.IsNullOrWhiteSpace(t)));
}
,然后
client.Search<Package>(s=>s
.From(0)
.Size(10)
.Filter(f=>
f.Term(p=>p.TargetBusiness.Industry, "Advertising")
&& f.Exists(p=>p.Name)
)
.Query(q=>
q.QueryString(qs=>qs
.Query(this.MyPackageQueryString(package))
.Operator(Operator.or)
)
)
)
确实使我走上了正确的轨道 - 最终看起来像是一种交叉搜索:搜索我不想要的其他每个字段的每个字段。
最终(可能错误地)与:
return _searchClient.Search<Package>(s => s.Query(q =>
q.Term("industry", criteriaPackage.TargetBusiness.Industry.ToLower()) ||
q.Term("description", criteriaPackage.TargetBusiness.Description.ToLower()) ||
q.Term("businessType",((int)criteriaPackage.TargetBusiness.BusinessType).ToString()) ||
q.Term("locationType", ((int)criteriaPackage.TargetBusiness.LocationType).ToString()) ||
q.Term("marketSegment", criteriaPackage.TargetBusiness.MarketSegment.ToLower()) ||
q.Term("offer", criteriaPackage.TargetBusiness.Offer.ToLower()))
).Documents;
在几个单位测试似乎正在产生我想要的结果之后。