-
Notifications
You must be signed in to change notification settings - Fork 24.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add
term
query support to rank_features mapped field (#93247)
This adds term query capabilities for rank_features fields. term queries against rank_features are not scored in the typical way as regular fields. This is because the stored feature values take advantage of the term frequency storage mechanism, and thus regular BM25 does not work. Instead, a term query against a rank_features field is very similar to linear rank_feature query. If more complicated combinations of features and values are required, the rank_feature query should be used.
- Loading branch information
Showing
4 changed files
with
137 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
pr: 93247 | ||
summary: Add `term` query support to `rank_features` mapped field | ||
area: Search | ||
type: enhancement | ||
issues: [] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
116 changes: 116 additions & 0 deletions
116
...ernalClusterTest/java/org/elasticsearch/index/mapper/RankFeaturesMapperIntegrationIT.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License | ||
* 2.0 and the Server Side Public License, v 1; you may not use this file except | ||
* in compliance with, at your election, the Elastic License 2.0 or the Server | ||
* Side Public License, v 1. | ||
*/ | ||
|
||
package org.elasticsearch.index.mapper; | ||
|
||
import org.elasticsearch.action.bulk.BulkResponse; | ||
import org.elasticsearch.action.search.SearchResponse; | ||
import org.elasticsearch.common.settings.Settings; | ||
import org.elasticsearch.index.mapper.extras.MapperExtrasPlugin; | ||
import org.elasticsearch.index.query.QueryBuilders; | ||
import org.elasticsearch.plugins.Plugin; | ||
import org.elasticsearch.search.SearchHit; | ||
import org.elasticsearch.test.ESIntegTestCase; | ||
|
||
import java.io.IOException; | ||
import java.util.Arrays; | ||
import java.util.Collection; | ||
import java.util.Map; | ||
|
||
import static org.elasticsearch.xcontent.XContentFactory.jsonBuilder; | ||
import static org.hamcrest.Matchers.equalTo; | ||
|
||
public class RankFeaturesMapperIntegrationIT extends ESIntegTestCase { | ||
|
||
private static final String LOWER_RANKED_FEATURE = "ten"; | ||
private static final String HIGHER_RANKED_FEATURE = "twenty"; | ||
private static final String INDEX_NAME = "rank_feature_test"; | ||
private static final String FIELD_NAME = "all_rank_features"; | ||
|
||
@Override | ||
protected Collection<Class<? extends Plugin>> nodePlugins() { | ||
return Arrays.asList(MapperExtrasPlugin.class); | ||
} | ||
|
||
public void testRankFeaturesTermQuery() throws IOException { | ||
init(); | ||
SearchResponse response = client().prepareSearch(INDEX_NAME) | ||
.setQuery(QueryBuilders.termQuery(FIELD_NAME, HIGHER_RANKED_FEATURE)) | ||
.get(); | ||
assertThat(response.getHits().getTotalHits().value, equalTo(2L)); | ||
for (SearchHit hit : response.getHits().getHits()) { | ||
assertThat(hit.getScore(), equalTo(20f)); | ||
} | ||
|
||
response = client().prepareSearch(INDEX_NAME) | ||
.setQuery(QueryBuilders.termQuery(FIELD_NAME, HIGHER_RANKED_FEATURE).boost(100f)) | ||
.get(); | ||
assertThat(response.getHits().getTotalHits().value, equalTo(2L)); | ||
for (SearchHit hit : response.getHits().getHits()) { | ||
assertThat(hit.getScore(), equalTo(2000f)); | ||
} | ||
|
||
response = client().prepareSearch(INDEX_NAME) | ||
.setQuery( | ||
QueryBuilders.boolQuery() | ||
.should(QueryBuilders.termQuery(FIELD_NAME, HIGHER_RANKED_FEATURE)) | ||
.should(QueryBuilders.termQuery(FIELD_NAME, LOWER_RANKED_FEATURE).boost(3f)) | ||
.minimumShouldMatch(1) | ||
) | ||
.get(); | ||
assertThat(response.getHits().getTotalHits().value, equalTo(3L)); | ||
for (SearchHit hit : response.getHits().getHits()) { | ||
if (hit.getId().equals("all")) { | ||
assertThat(hit.getScore(), equalTo(50f)); | ||
} | ||
if (hit.getId().equals("lower")) { | ||
assertThat(hit.getScore(), equalTo(30f)); | ||
} | ||
if (hit.getId().equals("higher")) { | ||
assertThat(hit.getScore(), equalTo(20f)); | ||
} | ||
} | ||
|
||
response = client().prepareSearch(INDEX_NAME).setQuery(QueryBuilders.termQuery(FIELD_NAME, "missing_feature")).get(); | ||
assertThat(response.getHits().getTotalHits().value, equalTo(0L)); | ||
} | ||
|
||
private void init() throws IOException { | ||
Settings.Builder settings = Settings.builder(); | ||
settings.put(indexSettings()); | ||
prepareCreate(INDEX_NAME).setSettings(settings) | ||
.setMapping( | ||
jsonBuilder().startObject() | ||
.startObject("_doc") | ||
.startObject("properties") | ||
.startObject("all_rank_features") | ||
.field("type", "rank_features") | ||
.endObject() | ||
.endObject() | ||
.endObject() | ||
.endObject() | ||
) | ||
.get(); | ||
ensureGreen(); | ||
|
||
BulkResponse bulk = client().prepareBulk() | ||
.add( | ||
client().prepareIndex(INDEX_NAME) | ||
.setId("all") | ||
.setSource(Map.of("all_rank_features", Map.of(LOWER_RANKED_FEATURE, 10, HIGHER_RANKED_FEATURE, 20))) | ||
) | ||
.add(client().prepareIndex(INDEX_NAME).setId("lower").setSource(Map.of("all_rank_features", Map.of(LOWER_RANKED_FEATURE, 10)))) | ||
.add( | ||
client().prepareIndex(INDEX_NAME).setId("higher").setSource(Map.of("all_rank_features", Map.of(HIGHER_RANKED_FEATURE, 20))) | ||
) | ||
.get(); | ||
assertFalse(bulk.buildFailureMessage(), bulk.hasFailures()); | ||
assertThat(refresh().getFailedShards(), equalTo(0)); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters