1 回答
TA贡献1773条经验 获得超3个赞
重新索引解决方案:
我最近从 ElasticSearch 找到了这个文档: https://www.elastic.co/guide/en/elasticsearch/guide/current/_finding_multiple_exact_values.html
由于倒排索引,TermQuery 和 TermsQuery 或 ElasticSearch 通常都使用“必须包含”而不是“必须等于”。
根据他们的说法,最好的解决方案是:
如果您确实想要这种行为——整个字段相等——实现它的最好方法是索引一个辅助字段。在此字段中,您索引字段包含的值的数量。使用我们之前的两个文档。将计数信息编入索引后,您可以构建一个 constant_score 来强制执行适当数量的术语。https://www.elastic.co/guide/en/elasticsearch/guide/current/_finding_multiple_exact_values.html#_equals_exactly
步骤如下:
在名为 exgroups_count 的索引中添加额外的映射。
使用 logstash 计算 exgroups 数组长度并放入 exgroups_count 字段。
保存索引。
没有重新索引的另一个解决方案:
添加和重新索引整个事物有一些限制。一旦您的索引增长,向索引添加字段和计算计数将是非常具有侵入性的 - 使其操作非常密集 - 更不用说您必须保存和维护您的映射。
我找到了一个不需要重新索引的解决方案。查看 ScriptQueryBuilder,理论上我可以添加一个脚本过滤器来计算数组的长度并等于 1。
"filter" : {
"script" : {
"script" : "doc['exgroups'].values.length == 1"
}
}
所以完整的查询现在变成这样:
"bool" : {
"must" : [
{
"term" : {
"exgroups" : {
"value" : "TSX",
"boost" : 1.0
}
}
}
],
"filter" : [
{
"script" : {
"script" : {
"source" : "doc['exgroups'].values.length == 1",
"lang" : "painless"
},
"boost" : 1.0
}
}
],
"adjust_pure_negative" : true,
"boost" : 1.0
}
在爪哇,
BoolQueryBuilder qBool = new BoolQueryBuilder();
TermQueryBuilder query = new TermQueryBuilder("exgroups", exchangeGroup.getCode());
qBool.must(query);
ScriptQueryBuilder sQuery = new ScriptQueryBuilder(new Script("doc['exgroups'].values.length == 1"));
qBool.filter(sQuery);
添加回答
举报