mirror of
https://github.com/honeymoose/OpenSearch.git
synced 2025-02-17 18:35:25 +00:00
Search: Allow to filter out docs based on a minimum score, closes #719.
This commit is contained in:
parent
a0fd47159e
commit
8a03ca1114
@ -229,6 +229,14 @@ public class SearchRequestBuilder extends BaseRequestBuilder<SearchRequest, Sear
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the minimum score below which docs will be filtered out.
|
||||||
|
*/
|
||||||
|
public SearchRequestBuilder setMinScore(float minScore) {
|
||||||
|
sourceBuilder().minScore(minScore);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* From index to start the search from. Defaults to <tt>0</tt>.
|
* From index to start the search from. Defaults to <tt>0</tt>.
|
||||||
*/
|
*/
|
||||||
|
@ -0,0 +1,66 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to Elastic Search and Shay Banon under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. Elastic Search licenses this
|
||||||
|
* file to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.elasticsearch.common.lucene;
|
||||||
|
|
||||||
|
import org.apache.lucene.index.IndexReader;
|
||||||
|
import org.apache.lucene.search.Collector;
|
||||||
|
import org.apache.lucene.search.ScoreCachingWrappingScorer;
|
||||||
|
import org.apache.lucene.search.Scorer;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class MinimumScoreCollector extends Collector {
|
||||||
|
|
||||||
|
private final Collector collector;
|
||||||
|
|
||||||
|
private final float minimumScore;
|
||||||
|
|
||||||
|
private Scorer scorer;
|
||||||
|
|
||||||
|
public MinimumScoreCollector(Collector collector, float minimumScore) {
|
||||||
|
this.collector = collector;
|
||||||
|
this.minimumScore = minimumScore;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public void setScorer(Scorer scorer) throws IOException {
|
||||||
|
if (!(scorer instanceof ScoreCachingWrappingScorer)) {
|
||||||
|
scorer = new ScoreCachingWrappingScorer(scorer);
|
||||||
|
}
|
||||||
|
this.scorer = scorer;
|
||||||
|
collector.setScorer(scorer);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public void collect(int doc) throws IOException {
|
||||||
|
if (scorer.score() > minimumScore) {
|
||||||
|
collector.collect(doc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public void setNextReader(IndexReader reader, int docBase) throws IOException {
|
||||||
|
collector.setNextReader(reader, docBase);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public boolean acceptsDocsOutOfOrder() {
|
||||||
|
return collector.acceptsDocsOutOfOrder();
|
||||||
|
}
|
||||||
|
}
|
@ -41,7 +41,8 @@ public class MultiCollector extends Collector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override public void setScorer(Scorer scorer) throws IOException {
|
@Override public void setScorer(Scorer scorer) throws IOException {
|
||||||
if (collectors.length > 0) {
|
// always wrap it in a scorer wrapper
|
||||||
|
if (!(scorer instanceof ScoreCachingWrappingScorer)) {
|
||||||
scorer = new ScoreCachingWrappingScorer(scorer);
|
scorer = new ScoreCachingWrappingScorer(scorer);
|
||||||
}
|
}
|
||||||
collector.setScorer(scorer);
|
collector.setScorer(scorer);
|
||||||
|
@ -88,6 +88,8 @@ public class SearchSourceBuilder implements ToXContent {
|
|||||||
|
|
||||||
private boolean trackScores = false;
|
private boolean trackScores = false;
|
||||||
|
|
||||||
|
private Float minScore;
|
||||||
|
|
||||||
private List<String> fieldNames;
|
private List<String> fieldNames;
|
||||||
|
|
||||||
private List<ScriptField> scriptFields;
|
private List<ScriptField> scriptFields;
|
||||||
@ -176,6 +178,14 @@ public class SearchSourceBuilder implements ToXContent {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the minimum score below which docs will be filtered out.
|
||||||
|
*/
|
||||||
|
public SearchSourceBuilder minScore(float minScore) {
|
||||||
|
this.minScore = minScore;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An optional query parser name to use.
|
* An optional query parser name to use.
|
||||||
*/
|
*/
|
||||||
@ -434,6 +444,10 @@ public class SearchSourceBuilder implements ToXContent {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (minScore != null) {
|
||||||
|
builder.field("min_score", minScore);
|
||||||
|
}
|
||||||
|
|
||||||
if (version != null) {
|
if (version != null) {
|
||||||
builder.field("version", version);
|
builder.field("version", version);
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,7 @@ import org.apache.lucene.index.IndexReader;
|
|||||||
import org.apache.lucene.search.*;
|
import org.apache.lucene.search.*;
|
||||||
import org.elasticsearch.common.collect.Lists;
|
import org.elasticsearch.common.collect.Lists;
|
||||||
import org.elasticsearch.common.collect.Maps;
|
import org.elasticsearch.common.collect.Maps;
|
||||||
|
import org.elasticsearch.common.lucene.MinimumScoreCollector;
|
||||||
import org.elasticsearch.common.lucene.MultiCollector;
|
import org.elasticsearch.common.lucene.MultiCollector;
|
||||||
import org.elasticsearch.common.lucene.search.ExtendedIndexSearcher;
|
import org.elasticsearch.common.lucene.search.ExtendedIndexSearcher;
|
||||||
import org.elasticsearch.common.lucene.search.FilteredCollector;
|
import org.elasticsearch.common.lucene.search.FilteredCollector;
|
||||||
@ -147,6 +148,11 @@ public class ContextIndexSearcher extends ExtendedIndexSearcher {
|
|||||||
collector = new MultiCollector(collector, collectors.toArray(new Collector[collectors.size()]));
|
collector = new MultiCollector(collector, collectors.toArray(new Collector[collectors.size()]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// apply the minimum score after multi collector so we filter facets as well
|
||||||
|
if (searchContext.minimumScore() != null) {
|
||||||
|
collector = new MinimumScoreCollector(collector, searchContext.minimumScore());
|
||||||
|
}
|
||||||
|
|
||||||
// we only compute the doc id set once since within a context, we execute the same query always...
|
// we only compute the doc id set once since within a context, we execute the same query always...
|
||||||
if (searchContext.timeout() != null) {
|
if (searchContext.timeout() != null) {
|
||||||
searchContext.queryResult().searchTimedOut(false);
|
searchContext.queryResult().searchTimedOut(false);
|
||||||
|
@ -115,6 +115,8 @@ public class SearchContext implements Releasable {
|
|||||||
|
|
||||||
private Sort sort;
|
private Sort sort;
|
||||||
|
|
||||||
|
private Float minimumScore;
|
||||||
|
|
||||||
private boolean trackScores = false; // when sorting, track scores as well...
|
private boolean trackScores = false; // when sorting, track scores as well...
|
||||||
|
|
||||||
private String queryParserName;
|
private String queryParserName;
|
||||||
@ -302,6 +304,15 @@ public class SearchContext implements Releasable {
|
|||||||
return timeout;
|
return timeout;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public SearchContext minimumScore(float minimumScore) {
|
||||||
|
this.minimumScore = minimumScore;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Float minimumScore() {
|
||||||
|
return this.minimumScore;
|
||||||
|
}
|
||||||
|
|
||||||
public SearchContext sort(Sort sort) {
|
public SearchContext sort(Sort sort) {
|
||||||
this.sort = sort;
|
this.sort = sort;
|
||||||
return this;
|
return this;
|
||||||
|
@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to Elastic Search and Shay Banon under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. Elastic Search licenses this
|
||||||
|
* file to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.elasticsearch.search.query;
|
||||||
|
|
||||||
|
import org.elasticsearch.common.xcontent.XContentParser;
|
||||||
|
import org.elasticsearch.search.SearchParseElement;
|
||||||
|
import org.elasticsearch.search.internal.SearchContext;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author kimchy (shay.banon)
|
||||||
|
*/
|
||||||
|
public class MinScoreParseElement implements SearchParseElement {
|
||||||
|
|
||||||
|
@Override public void parse(XContentParser parser, SearchContext context) throws Exception {
|
||||||
|
XContentParser.Token token = parser.currentToken();
|
||||||
|
if (token.isValue()) {
|
||||||
|
context.minimumScore(parser.floatValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -67,6 +67,8 @@ public class QueryPhase implements SearchPhase {
|
|||||||
.put("sort", new SortParseElement())
|
.put("sort", new SortParseElement())
|
||||||
.put("trackScores", new TrackScoresParseElement())
|
.put("trackScores", new TrackScoresParseElement())
|
||||||
.put("track_scores", new TrackScoresParseElement())
|
.put("track_scores", new TrackScoresParseElement())
|
||||||
|
.put("min_score", new MinScoreParseElement())
|
||||||
|
.put("minScore", new MinScoreParseElement())
|
||||||
.putAll(facetPhase.parseElements());
|
.putAll(facetPhase.parseElements());
|
||||||
return parseElements.build();
|
return parseElements.build();
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user