Return nothing instead of everything in MLT if no field is supported.
Today due the optimizations in the boolean query builder we adjust a pure negative query with a 'match_all'. This is not the desired behavior in the MLT API if all the fields in a document are unsupported. If that happens today we return all documents but the one MLT is executed on. Closes #3453
This commit is contained in:
parent
73c038fb48
commit
7f0115ba9a
|
@ -183,6 +183,7 @@ public class TransportMoreLikeThisAction extends TransportAction<MoreLikeThisReq
|
|||
// exclude myself
|
||||
Term uidTerm = docMapper.uidMapper().term(request.type(), request.id());
|
||||
boolBuilder.mustNot(termQuery(uidTerm.field(), uidTerm.text()));
|
||||
boolBuilder.adjustPureNegative(false);
|
||||
} catch (Throwable e) {
|
||||
listener.onFailure(e);
|
||||
return;
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
package org.elasticsearch.index.query;
|
||||
|
||||
import org.apache.lucene.search.MatchAllDocsQuery;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
|
||||
import java.io.IOException;
|
||||
|
@ -41,6 +42,8 @@ public class BoolQueryBuilder extends BaseQueryBuilder implements BoostableQuery
|
|||
private Boolean disableCoord;
|
||||
|
||||
private String minimumShouldMatch;
|
||||
|
||||
private Boolean adjustPureNegative;
|
||||
|
||||
/**
|
||||
* Adds a query that <b>must</b> appear in the matching documents.
|
||||
|
@ -119,6 +122,16 @@ public class BoolQueryBuilder extends BaseQueryBuilder implements BoostableQuery
|
|||
public boolean hasClauses() {
|
||||
return !mustClauses.isEmpty() || !mustNotClauses.isEmpty() || !shouldClauses.isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* If a boolean query contains only negative ("must not") clauses should the
|
||||
* BooleanQuery be enhanced with a {@link MatchAllDocsQuery} in order to act
|
||||
* as a pure exclude. The default is <code>true</code>.
|
||||
*/
|
||||
public BoolQueryBuilder adjustPureNegative(boolean adjustPureNegative) {
|
||||
this.adjustPureNegative = adjustPureNegative;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doXContent(XContentBuilder builder, Params params) throws IOException {
|
||||
|
@ -135,6 +148,9 @@ public class BoolQueryBuilder extends BaseQueryBuilder implements BoostableQuery
|
|||
if (minimumShouldMatch != null) {
|
||||
builder.field("minimum_should_match", minimumShouldMatch);
|
||||
}
|
||||
if (adjustPureNegative != null) {
|
||||
builder.field("adjust_pure_negative", adjustPureNegative);
|
||||
}
|
||||
builder.endObject();
|
||||
}
|
||||
|
||||
|
|
|
@ -60,7 +60,7 @@ public class BoolQueryParser implements QueryParser {
|
|||
String minimumShouldMatch = null;
|
||||
|
||||
List<BooleanClause> clauses = newArrayList();
|
||||
|
||||
boolean adjustPureNegative = true;
|
||||
String currentFieldName = null;
|
||||
XContentParser.Token token;
|
||||
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
|
||||
|
@ -119,6 +119,8 @@ public class BoolQueryParser implements QueryParser {
|
|||
boost = parser.floatValue();
|
||||
} else if ("minimum_number_should_match".equals(currentFieldName) || "minimumNumberShouldMatch".equals(currentFieldName)) {
|
||||
minimumShouldMatch = parser.textOrNull();
|
||||
} else if ("adjust_pure_negative".equals(currentFieldName) || "adjustPureNegative".equals(currentFieldName)) {
|
||||
adjustPureNegative = parser.booleanValue();
|
||||
} else {
|
||||
throw new QueryParsingException(parseContext.index(), "[bool] query does not support [" + currentFieldName + "]");
|
||||
}
|
||||
|
@ -135,6 +137,6 @@ public class BoolQueryParser implements QueryParser {
|
|||
}
|
||||
query.setBoost(boost);
|
||||
Queries.applyMinimumShouldMatch(query, minimumShouldMatch);
|
||||
return optimizeQuery(fixNegativeQueryIfNeeded(query));
|
||||
return optimizeQuery(adjustPureNegative ? fixNegativeQueryIfNeeded(query) : query);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -58,6 +58,27 @@ public class MoreLikeThisActionTests extends AbstractSharedClusterTest {
|
|||
SearchResponse mltResponse = client().moreLikeThis(moreLikeThisRequest("test").type("type1").id("1").minTermFreq(1).minDocFreq(1)).actionGet();
|
||||
assertHitCount(mltResponse, 1l);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testSimpleMoreLikeOnLongField() throws Exception {
|
||||
logger.info("Creating index test");
|
||||
createIndex("test");
|
||||
logger.info("Running Cluster Health");
|
||||
assertThat(ensureGreen(), equalTo(ClusterHealthStatus.GREEN));
|
||||
|
||||
logger.info("Indexing...");
|
||||
client().index(indexRequest("test").type("type1").id("1").source(jsonBuilder().startObject().field("some_long", 1367484649580l).endObject())).actionGet();
|
||||
client().index(indexRequest("test").type("type2").id("2").source(jsonBuilder().startObject().field("some_long", 0).endObject())).actionGet();
|
||||
client().index(indexRequest("test").type("type1").id("3").source(jsonBuilder().startObject().field("some_long", -666).endObject())).actionGet();
|
||||
|
||||
|
||||
client().admin().indices().refresh(refreshRequest()).actionGet();
|
||||
|
||||
logger.info("Running moreLikeThis");
|
||||
SearchResponse mltResponse = client().moreLikeThis(moreLikeThisRequest("test").type("type1").id("1").minTermFreq(1).minDocFreq(1)).actionGet();
|
||||
assertHitCount(mltResponse, 0l);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
|
|
Loading…
Reference in New Issue