/**
* Constructs a new text query.
*/
public MultiMatchQueryBuilder(Object value, String... fields) {
if (value == null) {
throw new IllegalArgumentException("[" + NAME + "] requires query value");
}
if (fields == null) {
throw new IllegalArgumentException("[" + NAME + "] requires fields at initialization time");
}
this.value = value;
this.fieldsBoosts = new TreeMap<>();
### 调用field()方法添加字段
for (String field : fields) {
field(field);
}
}
...........
/**
* Adds a field to run the multi match against.
*/
public MultiMatchQueryBuilder field(String field) {
if (Strings.isEmpty(field)) {
throw new IllegalArgumentException("supplied field is null or empty.");
}
#### 添加的字段都设置了一个默认的DEFAULT_BOOST
this.fieldsBoosts.put(field, AbstractQueryBuilder.DEFAULT_BOOST);
return this;
}
不过有一个fileds()方法,可以添加自定义boost的字段
/**
* Add several fields to run the query against with a specific boost.
*/
public MultiMatchQueryBuilder fields(Map<String, Float> fields) {
this.fieldsBoosts.putAll(fields);
return this;
}
QueryBuilder qb = QueryBuilders.matchAllQuery();
List<QueryItem> queryItems = request.getQueryItems();
if (!(null == queryItems || queryItems.isEmpty())) {
qb = new MultiMatchQueryBuilder(request.getQueryText());
if (StringUtils.isNotBlank(request.getMultiQueryType())) {
((MultiMatchQueryBuilder) qb).type(request.getMultiQueryType());
}
if (StringUtils.isNotBlank(request.getMultiQueryOperator())) {
if (MultiQueryOperator.AND.equals(request.getMultiQueryOperator().toUpperCase())) {
((MultiMatchQueryBuilder) qb).operator(Operator.AND);
} else if (MultiQueryOperator.OR.equals(request.getMultiQueryOperator().toUpperCase())) {
((MultiMatchQueryBuilder) qb).operator(Operator.OR);
}
} else {
((MultiMatchQueryBuilder) qb).operator(Operator.AND);
}
// set query
for (int i = 0; i < queryItems.size(); i ++) {
QueryItem tqi = queryItems.get(i);
((MultiMatchQueryBuilder) qb).field(tqi.getField(), tqi.getBoost());
}
}
4 个回复
kennywu76 - Wood
赞同来自: zev 、denghc0607
看了下multiMatchQuery的源码,的确会给所有的fields加一个默认的boost 1.0,造成字段上给的权重值被当作了field的一部分。
不过有一个fileds()方法,可以添加自定义boost的字段
其中fileds是一个字段名称为key, boost数值为value的Map。
因此,你可以这么来构造Query:
也就是调用已fields方法,并传入自定义权重的map作为参数。
PS. 官方的client SDK文档不够详细,没有对此做说明。
kennywu76 - Wood
赞同来自: zev
God_lockin
赞同来自: sodyu
"queryItems":[ // 设定目标字段及权重值
{
"field":"title", // 字段名
"boost":15 // 权重值,float 型
}
"queryText":"住院", // 如果填,则是各字段中需要被检索的内容
"multiQueryOperator":"and", // 可选,默认 and, 补全检索逻辑条件
"multiQueryType":"most_fields", // 可选,best_fields / most_fields / cross_fields / phrase / phrase_prefix
组合出来的query,再在SearchRequestBuilder里面builder.setQuery(qb);
就可以执行
SearchResponse esResponse = builder.execute().actionGet();
来取结果了
zev
赞同来自: