Query Refactoring: Move MoreLikeThisQueryBuilder validation to constructor

The current MoreLikeThisQueryBuilder validation checks for existence of at
least one `like` text or item. This is hard to check in setters, so this PR
tries to change the construction of the query so that we can do these checks
already at construction time.

Changing to using arrays for fieldnames, likeTexts, likeItems, unlikeTexts
and unlikeItems. `likeTexts` and/or `likeItems` need to be specified at
construction time to validate we have at least one item there.

Relates to #10217
This commit is contained in:
Christoph Büscher 2015-09-21 20:05:19 +02:00
parent 7eedd84dc3
commit dbb01f5b43
10 changed files with 210 additions and 221 deletions

View File

@ -158,7 +158,7 @@ public class MoreLikeThisQuery extends Query {
if (this.unlikeText != null || this.unlikeFields != null) {
handleUnlike(mlt, this.unlikeText, this.unlikeFields);
}
return createQuery(mlt);
}
@ -182,7 +182,7 @@ public class MoreLikeThisQuery extends Query {
BooleanQuery bq = bqBuilder.build();
bq.setBoost(getBoost());
return bq;
return bq;
}
private void handleUnlike(XMoreLikeThis mlt, String[] unlikeText, Fields[] unlikeFields) throws IOException {
@ -257,8 +257,8 @@ public class MoreLikeThisQuery extends Query {
this.unlikeFields = unlikeFields;
}
public void setUnlikeText(List<String> unlikeText) {
this.unlikeText = unlikeText.toArray(Strings.EMPTY_ARRAY);
public void setUnlikeText(String[] unlikeText) {
this.unlikeText = unlikeText;
}
public String[] getMoreLikeFields() {

View File

@ -75,11 +75,11 @@ public class MoreLikeThisQueryBuilder extends AbstractQueryBuilder<MoreLikeThisQ
public static final boolean DEFAULT_FAIL_ON_UNSUPPORTED_FIELDS = true;
// document inputs
private final List<String> fields;
private List<String> likeTexts = new ArrayList<>();
private List<String> unlikeTexts = new ArrayList<>();
private List<Item> likeItems = new ArrayList<>();
private List<Item> unlikeItems = new ArrayList<>();
private final String[] fields;
private final String[] likeTexts;
private String[] unlikeTexts = Strings.EMPTY_ARRAY;
private final Item[] likeItems;
private Item[] unlikeItems = new Item[0];
// term selection parameters
private int maxQueryTerms = DEFAULT_MAX_QUERY_TERMS;
@ -99,7 +99,7 @@ public class MoreLikeThisQueryBuilder extends AbstractQueryBuilder<MoreLikeThisQ
// other parameters
private boolean failOnUnsupportedField = DEFAULT_FAIL_ON_UNSUPPORTED_FIELDS;
static final MoreLikeThisQueryBuilder PROTOTYPE = new MoreLikeThisQueryBuilder();
static final MoreLikeThisQueryBuilder PROTOTYPE = new MoreLikeThisQueryBuilder(new String[]{"_na_"}, null);
/**
* A single item to be used for a {@link MoreLikeThisQueryBuilder}.
@ -437,82 +437,66 @@ public class MoreLikeThisQueryBuilder extends AbstractQueryBuilder<MoreLikeThisQ
/**
* Constructs a new more like this query which uses the "_all" field.
*/
public MoreLikeThisQueryBuilder() {
this.fields = null;
}
/**
* Sets the field names that will be used when generating the 'More Like This' query.
*
* @param fields the field names that will be used when generating the 'More Like This' query.
*/
public MoreLikeThisQueryBuilder(String... fields) {
this(Collections.unmodifiableList(Arrays.asList(fields)));
}
/**
* Sets the field names that will be used when generating the 'More Like This' query.
*
* @param fields the field names that will be used when generating the 'More Like This' query.
*/
public MoreLikeThisQueryBuilder(List<String> fields) {
this.fields = fields;
}
public List<String> fields() {
return fields;
}
/**
* Sets the text to use in order to find documents that are "like" this.
*
* @param likeTexts the text to use when generating the 'More Like This' query.
* @param likeItems the documents to use when generating the 'More Like This' query.
*/
public MoreLikeThisQueryBuilder like(String... likeTexts) {
this.likeTexts = Collections.unmodifiableList(Arrays.asList(likeTexts));
return this;
public MoreLikeThisQueryBuilder(String[] likeTexts, Item[] likeItems) {
this(null, likeTexts, likeItems);
}
public List<String> likeTexts() {
/**
* Sets the field names that will be used when generating the 'More Like This' query.
*
* @param fields the field names that will be used when generating the 'More Like This' query.
* @param likeTexts the text to use when generating the 'More Like This' query.
* @param likeItems the documents to use when generating the 'More Like This' query.
*/
public MoreLikeThisQueryBuilder(@Nullable String[] fields, @Nullable String[] likeTexts, @Nullable Item[] likeItems) {
// TODO we allow null here for the _all field, but this is forbidden in the parser. Re-check
if (fields != null && fields.length == 0) {
throw new IllegalArgumentException("mlt query requires 'fields' to be specified");
}
if ((likeTexts == null || likeTexts.length == 0) && (likeItems == null || likeItems.length == 0)) {
throw new IllegalArgumentException("mlt query requires either 'like' texts or items to be specified.");
}
this.fields = fields;
this.likeTexts = Optional.ofNullable(likeTexts).orElse(Strings.EMPTY_ARRAY);
this.likeItems = Optional.ofNullable(likeItems).orElse(new Item[0]);
}
public String[] fields() {
return this.fields;
}
public String[] likeTexts() {
return likeTexts;
}
/**
* Sets the documents to use in order to find documents that are "like" this.
*
* @param likeItems the documents to use when generating the 'More Like This' query.
*/
public MoreLikeThisQueryBuilder like(Item... likeItems) {
this.likeItems = Collections.unmodifiableList(Arrays.asList(likeItems));
return this;
}
public List<Item> likeItems() {
public Item[] likeItems() {
return likeItems;
}
/**
* Sets the text from which the terms should not be selected from.
*/
public MoreLikeThisQueryBuilder unlike(String... unlikeTexts) {
this.unlikeTexts = Collections.unmodifiableList(Arrays.asList(unlikeTexts));
public MoreLikeThisQueryBuilder unlike(String[] unlikeTexts) {
this.unlikeTexts = Optional.ofNullable(unlikeTexts).orElse(Strings.EMPTY_ARRAY);
return this;
}
public List<String> unlikeTexts() {
public String[] unlikeTexts() {
return unlikeTexts;
}
/**
* Sets the documents from which the terms should not be selected from.
*/
public MoreLikeThisQueryBuilder unlike(Item... unlikeItems) {
this.unlikeItems = Collections.unmodifiableList(Arrays.asList(unlikeItems));
public MoreLikeThisQueryBuilder unlike(Item[] unlikeItems) {
this.unlikeItems = Optional.ofNullable(unlikeItems).orElse(new Item[0]);
return this;
}
public List<Item> unlikeItems() {
public Item[] unlikeItems() {
return unlikeItems;
}
@ -685,20 +669,18 @@ public class MoreLikeThisQueryBuilder extends AbstractQueryBuilder<MoreLikeThisQ
}
/**
* The text to use in order to find documents that are "like" this.
* Converts an array of String ids to and Item[].
* @param ids the ids to convert
* @return the new items array
* @deprecated construct the items array externaly and use it in the constructor / setter
*/
@Deprecated
public MoreLikeThisQueryBuilder likeText(String likeText) {
return like(likeText);
}
@Deprecated
public MoreLikeThisQueryBuilder ids(String... ids) {
public static Item[] ids(String... ids) {
Item[] items = new Item[ids.length];
for (int i = 0; i < items.length; i++) {
items[i] = new Item(null, null, ids[i]);
}
return like(items);
return items;
}
@Override
@ -708,9 +690,7 @@ public class MoreLikeThisQueryBuilder extends AbstractQueryBuilder<MoreLikeThisQ
builder.field(MoreLikeThisQueryParser.Field.FIELDS.getPreferredName(), fields);
}
buildLikeField(builder, MoreLikeThisQueryParser.Field.LIKE.getPreferredName(), likeTexts, likeItems);
if (!unlikeTexts.isEmpty() || !unlikeItems.isEmpty()) {
buildLikeField(builder, MoreLikeThisQueryParser.Field.UNLIKE.getPreferredName(), unlikeTexts, unlikeItems);
}
buildLikeField(builder, MoreLikeThisQueryParser.Field.UNLIKE.getPreferredName(), unlikeTexts, unlikeItems);
builder.field(MoreLikeThisQueryParser.Field.MAX_QUERY_TERMS.getPreferredName(), maxQueryTerms);
builder.field(MoreLikeThisQueryParser.Field.MIN_TERM_FREQ.getPreferredName(), minTermFreq);
builder.field(MoreLikeThisQueryParser.Field.MIN_DOC_FREQ.getPreferredName(), minDocFreq);
@ -731,15 +711,17 @@ public class MoreLikeThisQueryBuilder extends AbstractQueryBuilder<MoreLikeThisQ
builder.endObject();
}
private static void buildLikeField(XContentBuilder builder, String fieldName, List<String> texts, List<Item> items) throws IOException {
builder.startArray(fieldName);
for (String text : texts) {
builder.value(text);
private static void buildLikeField(XContentBuilder builder, String fieldName, String[] texts, Item[] items) throws IOException {
if (texts.length > 0 || items.length > 0) {
builder.startArray(fieldName);
for (String text : texts) {
builder.value(text);
}
for (Item item : items) {
builder.value(item);
}
builder.endArray();
}
for (Item item : items) {
builder.value(item);
}
builder.endArray();
}
@Override
@ -799,15 +781,15 @@ public class MoreLikeThisQueryBuilder extends AbstractQueryBuilder<MoreLikeThisQ
mltQuery.setMoreLikeFields(moreLikeFields.toArray(Strings.EMPTY_ARRAY));
// handle like texts
if (likeTexts.isEmpty() == false) {
if (likeTexts.length > 0) {
mltQuery.setLikeText(likeTexts);
}
if (unlikeTexts.isEmpty() == false) {
if (unlikeTexts.length > 0) {
mltQuery.setUnlikeText(unlikeTexts);
}
// handle items
if (likeItems.isEmpty() == false) {
if (likeItems.length > 0) {
return handleItems(context, mltQuery, likeItems, unlikeItems, include, moreLikeFields, useDefaultField);
} else {
return mltQuery;
@ -828,7 +810,7 @@ public class MoreLikeThisQueryBuilder extends AbstractQueryBuilder<MoreLikeThisQ
return moreLikeFields;
}
private Query handleItems(QueryShardContext context, MoreLikeThisQuery mltQuery, List<Item> likeItems, List<Item> unlikeItems,
private Query handleItems(QueryShardContext context, MoreLikeThisQuery mltQuery, Item[] likeItems, Item[] unlikeItems,
boolean include, List<String> moreLikeFields, boolean useDefaultField) throws IOException {
// set default index, type and fields if not specified
for (Item item : likeItems) {
@ -845,7 +827,7 @@ public class MoreLikeThisQueryBuilder extends AbstractQueryBuilder<MoreLikeThisQ
mltQuery.setLikeText(getFieldsFor(responses, likeItems));
// getting the Fields for unliked items
if (!unlikeItems.isEmpty()) {
if (unlikeItems.length > 0) {
org.apache.lucene.index.Fields[] unlikeFields = getFieldsFor(responses, unlikeItems);
if (unlikeFields.length > 0) {
mltQuery.setUnlikeText(unlikeFields);
@ -885,22 +867,20 @@ public class MoreLikeThisQueryBuilder extends AbstractQueryBuilder<MoreLikeThisQ
}
}
private MultiTermVectorsResponse fetchResponse(Client client, List<Item> likeItems, @Nullable List<Item> unlikeItems,
private MultiTermVectorsResponse fetchResponse(Client client, Item[] likeItems, @Nullable Item[] unlikeItems,
SearchContext searchContext) throws IOException {
MultiTermVectorsRequest request = new MultiTermVectorsRequest();
for (Item item : likeItems) {
request.add(item.toTermVectorsRequest());
}
if (unlikeItems != null) {
for (Item item : unlikeItems) {
request.add(item.toTermVectorsRequest());
}
for (Item item : unlikeItems) {
request.add(item.toTermVectorsRequest());
}
request.copyContextAndHeadersFrom(searchContext);
return client.multiTermVectors(request).actionGet();
}
private static Fields[] getFieldsFor(MultiTermVectorsResponse responses, List<Item> items) throws IOException {
private static Fields[] getFieldsFor(MultiTermVectorsResponse responses, Item[] items) throws IOException {
List<Fields> likeFields = new ArrayList<>();
Set<Item> selectedItems = new HashSet<>();
@ -928,7 +908,7 @@ public class MoreLikeThisQueryBuilder extends AbstractQueryBuilder<MoreLikeThisQ
return selectedItems.contains(new Item(response.getIndex(), response.getType(), response.getId()));
}
private static void handleExclude(BooleanQuery boolQuery, List<Item> likeItems) {
private static void handleExclude(BooleanQuery boolQuery, Item[] likeItems) {
// artificial docs get assigned a random id and should be disregarded
List<BytesRef> uids = new ArrayList<>();
for (Item item : likeItems) {
@ -943,23 +923,13 @@ public class MoreLikeThisQueryBuilder extends AbstractQueryBuilder<MoreLikeThisQ
}
}
public QueryValidationException validate() {
QueryValidationException validationException = null;
if (likeTexts.isEmpty() && likeItems.isEmpty()) {
validationException = addValidationError("requires 'like' to be specified.", validationException);
}
if (fields != null && fields.isEmpty()) {
validationException = addValidationError("requires 'fields' to be specified", validationException);
}
return validationException;
}
@Override
protected MoreLikeThisQueryBuilder doReadFrom(StreamInput in) throws IOException {
MoreLikeThisQueryBuilder moreLikeThisQueryBuilder = new MoreLikeThisQueryBuilder((List<String>) in.readGenericValue());
moreLikeThisQueryBuilder.likeTexts = (List<String>) in.readGenericValue();
moreLikeThisQueryBuilder.unlikeTexts = (List<String>) in.readGenericValue();
moreLikeThisQueryBuilder.likeItems = readItems(in);
String[] fields = in.readOptionalStringArray();
String[] likeTexts = in.readStringArray();
Item[] likeItems = readItems(in);
MoreLikeThisQueryBuilder moreLikeThisQueryBuilder = new MoreLikeThisQueryBuilder(fields, likeTexts, likeItems);
moreLikeThisQueryBuilder.unlikeTexts = in.readStringArray();
moreLikeThisQueryBuilder.unlikeItems = readItems(in);
moreLikeThisQueryBuilder.maxQueryTerms = in.readVInt();
moreLikeThisQueryBuilder.minTermFreq = in.readVInt();
@ -976,21 +946,21 @@ public class MoreLikeThisQueryBuilder extends AbstractQueryBuilder<MoreLikeThisQ
return moreLikeThisQueryBuilder;
}
private static List<Item> readItems(StreamInput in) throws IOException {
List<Item> items = new ArrayList<>();
private static Item[] readItems(StreamInput in) throws IOException {
int size = in.readVInt();
Item[] items = new Item[size];
for (int i = 0; i < size; i++) {
items.add(Item.readItemFrom(in));
items[i] = Item.readItemFrom(in);
}
return items;
}
@Override
protected void doWriteTo(StreamOutput out) throws IOException {
out.writeGenericValue(fields);
out.writeGenericValue(likeTexts);
out.writeGenericValue(unlikeTexts);
out.writeOptionalStringArray(fields);
out.writeStringArray(likeTexts);
writeItems(likeItems, out);
out.writeStringArray(unlikeTexts);
writeItems(unlikeItems, out);
out.writeVInt(maxQueryTerms);
out.writeVInt(minTermFreq);
@ -1006,8 +976,8 @@ public class MoreLikeThisQueryBuilder extends AbstractQueryBuilder<MoreLikeThisQ
out.writeBoolean(failOnUnsupportedField);
}
private static void writeItems(List<Item> items, StreamOutput out) throws IOException {
out.writeVInt(items.size());
private static void writeItems(Item[] items, StreamOutput out) throws IOException {
out.writeVInt(items.length);
for (Item item : items) {
item.writeTo(out);
}
@ -1015,18 +985,19 @@ public class MoreLikeThisQueryBuilder extends AbstractQueryBuilder<MoreLikeThisQ
@Override
protected int doHashCode() {
return Objects.hash(fields, likeTexts, unlikeTexts, likeItems, unlikeItems, maxQueryTerms, minTermFreq,
minDocFreq, maxDocFreq, minWordLength, maxWordLength, Arrays.hashCode(stopWords), analyzer, minimumShouldMatch,
boostTerms, include, failOnUnsupportedField);
return Objects.hash(Arrays.hashCode(fields), Arrays.hashCode(likeTexts),
Arrays.hashCode(unlikeTexts), Arrays.hashCode(likeItems), Arrays.hashCode(unlikeItems),
maxQueryTerms, minTermFreq, minDocFreq, maxDocFreq, minWordLength, maxWordLength,
Arrays.hashCode(stopWords), analyzer, minimumShouldMatch, boostTerms, include, failOnUnsupportedField);
}
@Override
protected boolean doEquals(MoreLikeThisQueryBuilder other) {
return Objects.equals(fields, other.fields) &&
Objects.equals(likeTexts, other.likeTexts) &&
Objects.equals(unlikeTexts, other.unlikeTexts) &&
Objects.equals(likeItems, other.likeItems) &&
Objects.equals(unlikeItems, other.unlikeItems) &&
return Arrays.equals(fields, other.fields) &&
Arrays.equals(likeTexts, other.likeTexts) &&
Arrays.equals(unlikeTexts, other.unlikeTexts) &&
Arrays.equals(likeItems, other.likeItems) &&
Arrays.equals(unlikeItems, other.unlikeItems) &&
Objects.equals(maxQueryTerms, other.maxQueryTerms) &&
Objects.equals(minTermFreq, other.minTermFreq) &&
Objects.equals(minDocFreq, other.minDocFreq) &&

View File

@ -187,11 +187,15 @@ public class MoreLikeThisQueryParser extends BaseQueryParser<MoreLikeThisQueryBu
throw new ParsingException(parser.getTokenLocation(), "more_like_this requires 'fields' to be non-empty");
}
MoreLikeThisQueryBuilder moreLikeThisQueryBuilder = new MoreLikeThisQueryBuilder(fields)
.like(likeTexts.toArray(new String[likeTexts.size()]))
.unlike(unlikeTexts.toArray(new String[unlikeTexts.size()]))
.like(likeItems.toArray(new Item[likeItems.size()]))
.unlike(unlikeItems.toArray(new Item[unlikeItems.size()]))
String[] fieldsArray = fields == null ? null : fields.toArray(new String[fields.size()]);
String[] likeTextsArray = likeTexts.isEmpty() ? null : likeTexts.toArray(new String[likeTexts.size()]);
String[] unlikeTextsArray = unlikeTexts.isEmpty() ? null : unlikeTexts.toArray(new String[unlikeTexts.size()]);
Item[] likeItemsArray = likeItems.isEmpty() ? null : likeItems.toArray(new Item[likeItems.size()]);
Item[] unlikeItemsArray = unlikeItems.isEmpty() ? null : unlikeItems.toArray(new Item[unlikeItems.size()]);
MoreLikeThisQueryBuilder moreLikeThisQueryBuilder = new MoreLikeThisQueryBuilder(fieldsArray, likeTextsArray, likeItemsArray)
.unlike(unlikeTextsArray)
.unlike(unlikeItemsArray)
.maxQueryTerms(maxQueryTerms)
.minTermFreq(minTermFreq)
.minDocFreq(minDocFreq)

View File

@ -24,6 +24,7 @@ import org.elasticsearch.common.bytes.BytesReference;
import org.elasticsearch.common.geo.GeoPoint;
import org.elasticsearch.common.geo.ShapeRelation;
import org.elasticsearch.common.geo.builders.ShapeBuilder;
import org.elasticsearch.index.query.MoreLikeThisQueryBuilder.Item;
import org.elasticsearch.index.query.functionscore.FunctionScoreQueryBuilder;
import org.elasticsearch.index.query.functionscore.ScoreFunctionBuilder;
import org.elasticsearch.index.search.MatchQuery;
@ -422,21 +423,43 @@ public abstract class QueryBuilders {
}
/**
* A more like this query that finds documents that are "like" the provided {@link MoreLikeThisQueryBuilder#likeText(String)}
* A more like this query that finds documents that are "like" the provided texts or documents
* which is checked against the fields the query is constructed with.
*
* @param fields The fields to run the query against
* @param fields the field names that will be used when generating the 'More Like This' query.
* @param likeTexts the text to use when generating the 'More Like This' query.
* @param likeItems the documents to use when generating the 'More Like This' query.
*/
public static MoreLikeThisQueryBuilder moreLikeThisQuery(String... fields) {
return new MoreLikeThisQueryBuilder(fields);
public static MoreLikeThisQueryBuilder moreLikeThisQuery(String[] fields, String[] likeTexts, Item[] likeItems) {
return new MoreLikeThisQueryBuilder(fields, likeTexts, likeItems);
}
/**
* A more like this query that finds documents that are "like" the provided {@link MoreLikeThisQueryBuilder#likeText(String)}
* A more like this query that finds documents that are "like" the provided texts or documents
* which is checked against the "_all" field.
* @param likeTexts the text to use when generating the 'More Like This' query.
* @param likeItems the documents to use when generating the 'More Like This' query.
*/
public static MoreLikeThisQueryBuilder moreLikeThisQuery() {
return new MoreLikeThisQueryBuilder();
public static MoreLikeThisQueryBuilder moreLikeThisQuery(String[] likeTexts, Item[] likeItems) {
return moreLikeThisQuery(null, likeTexts, likeItems);
}
/**
* A more like this query that finds documents that are "like" the provided texts
* which is checked against the "_all" field.
* @param likeTexts the text to use when generating the 'More Like This' query.
*/
public static MoreLikeThisQueryBuilder moreLikeThisQuery(String[] likeTexts) {
return moreLikeThisQuery(null, likeTexts, null);
}
/**
* A more like this query that finds documents that are "like" the provided documents
* which is checked against the "_all" field.
* @param likeItems the documents to use when generating the 'More Like This' query.
*/
public static MoreLikeThisQueryBuilder moreLikeThisQuery(Item[] likeItems) {
return moreLikeThisQuery(null, null, likeItems);
}
/**

View File

@ -26,9 +26,12 @@ import org.apache.lucene.index.memory.MemoryIndex;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.Query;
import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.action.termvectors.*;
import org.elasticsearch.action.termvectors.MultiTermVectorsItemResponse;
import org.elasticsearch.action.termvectors.MultiTermVectorsRequest;
import org.elasticsearch.action.termvectors.MultiTermVectorsResponse;
import org.elasticsearch.action.termvectors.TermVectorsRequest;
import org.elasticsearch.action.termvectors.TermVectorsResponse;
import org.elasticsearch.common.ParseFieldMatcher;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.io.stream.BytesStreamOutput;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.lucene.search.MoreLikeThisQuery;
@ -49,8 +52,6 @@ import java.util.HashMap;
import java.util.Map;
import java.util.stream.Stream;
import static org.hamcrest.Matchers.is;
public class MoreLikeThisQueryBuilderTests extends AbstractQueryTestCase<MoreLikeThisQueryBuilder> {
private static String[] randomFields;
@ -133,17 +134,20 @@ public class MoreLikeThisQueryBuilderTests extends AbstractQueryTestCase<MoreLik
@Override
protected MoreLikeThisQueryBuilder doCreateTestQueryBuilder() {
MoreLikeThisQueryBuilder queryBuilder;
if (randomBoolean()) { // for the default field
queryBuilder = new MoreLikeThisQueryBuilder();
} else {
queryBuilder = new MoreLikeThisQueryBuilder(randomFields);
}
String[] likeTexts = null;
Item[] likeItems = null;
// like field is required
if (randomBoolean()) {
queryBuilder.like(generateRandomStringArray(5, 5, false, false));
likeTexts = generateRandomStringArray(5, 5, false, false);
} else {
queryBuilder.like(randomLikeItems);
likeItems = randomLikeItems;
}
if (randomBoolean()) { // for the default field
queryBuilder = new MoreLikeThisQueryBuilder(likeTexts, likeItems);
} else {
queryBuilder = new MoreLikeThisQueryBuilder(randomFields, likeTexts, likeItems);
}
if (randomBoolean()) {
queryBuilder.unlike(generateRandomStringArray(5, 5, false, false));
}
@ -228,7 +232,7 @@ public class MoreLikeThisQueryBuilderTests extends AbstractQueryTestCase<MoreLik
@Override
protected void doAssertLuceneQuery(MoreLikeThisQueryBuilder queryBuilder, Query query, QueryShardContext context) throws IOException {
if (!queryBuilder.likeItems().isEmpty()) {
if (queryBuilder.likeItems() != null && queryBuilder.likeItems().length > 0) {
assertThat(query, Matchers.instanceOf(BooleanQuery.class));
} else {
// we rely on integration tests for a deeper check here
@ -236,30 +240,23 @@ public class MoreLikeThisQueryBuilderTests extends AbstractQueryTestCase<MoreLik
}
}
@Test
public void testValidate() {
MoreLikeThisQueryBuilder queryBuilder = new MoreLikeThisQueryBuilder(Strings.EMPTY_ARRAY);
assertThat(queryBuilder.validate().validationErrors().size(), is(2));
@Test(expected=IllegalArgumentException.class)
public void testValidateEmptyFields() {
new MoreLikeThisQueryBuilder(new String[0], new String[]{"likeText"}, null);
}
queryBuilder = new MoreLikeThisQueryBuilder(Strings.EMPTY_ARRAY).like("some text");
assertThat(queryBuilder.validate().validationErrors().size(), is(1));
queryBuilder = new MoreLikeThisQueryBuilder("field").like(Strings.EMPTY_ARRAY);
assertThat(queryBuilder.validate().validationErrors().size(), is(1));
queryBuilder = new MoreLikeThisQueryBuilder("field").like(Item.EMPTY_ARRAY);
assertThat(queryBuilder.validate().validationErrors().size(), is(1));
queryBuilder = new MoreLikeThisQueryBuilder("field").like("some text");
assertNull(queryBuilder.validate());
@Test(expected=IllegalArgumentException.class)
public void testValidateEmptyLike() {
String[] likeTexts = randomBoolean() ? null : new String[0];
Item[] likeItems = randomBoolean() ? null : new Item[0];
new MoreLikeThisQueryBuilder(likeTexts, likeItems);
}
@Test
public void testUnsupportedFields() throws IOException {
assumeTrue("test runs only when at least a type is registered", getCurrentTypes().length > 0);
String unsupportedField = randomFrom(INT_FIELD_NAME, DOUBLE_FIELD_NAME, DATE_FIELD_NAME);
MoreLikeThisQueryBuilder queryBuilder = new MoreLikeThisQueryBuilder(unsupportedField)
.like("some text")
MoreLikeThisQueryBuilder queryBuilder = new MoreLikeThisQueryBuilder(new String[] {unsupportedField}, new String[]{"some text"}, null)
.failOnUnsupportedField(true);
try {
queryBuilder.toQuery(createShardContext());

View File

@ -1231,7 +1231,7 @@ public class SimpleIndexQueryParserTests extends ESSingleNodeTestCase {
@Test
public void testMoreLikeThisBuilder() throws Exception {
IndexQueryParserService queryParser = queryParser();
Query parsedQuery = queryParser.parse(moreLikeThisQuery("name.first", "name.last").likeText("something").minTermFreq(1).maxQueryTerms(12)).query();
Query parsedQuery = queryParser.parse(moreLikeThisQuery(new String[] {"name.first", "name.last"}, new String[] {"something"}, null).minTermFreq(1).maxQueryTerms(12)).query();
assertThat(parsedQuery, instanceOf(MoreLikeThisQuery.class));
MoreLikeThisQuery mltQuery = (MoreLikeThisQuery) parsedQuery;
assertThat(mltQuery.getMoreLikeFields()[0], equalTo("name.first"));

View File

@ -39,6 +39,7 @@ import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import static org.elasticsearch.index.query.MoreLikeThisQueryBuilder.ids;
import static org.elasticsearch.client.Requests.*;
import static org.elasticsearch.cluster.metadata.IndexMetaData.SETTING_NUMBER_OF_REPLICAS;
import static org.elasticsearch.cluster.metadata.IndexMetaData.SETTING_NUMBER_OF_SHARDS;
@ -72,7 +73,7 @@ public class MoreLikeThisIT extends ESIntegTestCase {
logger.info("Running moreLikeThis");
SearchResponse response = client().prepareSearch().setQuery(
new MoreLikeThisQueryBuilder().like(new Item("test", "type1", "1")).minTermFreq(1).minDocFreq(1)).get();
new MoreLikeThisQueryBuilder(null, new Item[] {new Item("test", "type1", "1")}).minTermFreq(1).minDocFreq(1)).get();
assertHitCount(response, 1l);
}
@ -92,7 +93,7 @@ public class MoreLikeThisIT extends ESIntegTestCase {
logger.info("Running moreLikeThis");
SearchResponse response = client().prepareSearch().setQuery(
new MoreLikeThisQueryBuilder().like(new Item("test", "type1", "1")).minTermFreq(1).minDocFreq(1)).get();
new MoreLikeThisQueryBuilder(null, new Item[] {new Item("test", "type1", "1")}).minTermFreq(1).minDocFreq(1)).get();
assertHitCount(response, 0l);
}
@ -119,24 +120,24 @@ public class MoreLikeThisIT extends ESIntegTestCase {
logger.info("Running moreLikeThis on index");
SearchResponse response = client().prepareSearch().setQuery(
new MoreLikeThisQueryBuilder().like(new Item("test", "type1", "1")).minTermFreq(1).minDocFreq(1)).get();
new MoreLikeThisQueryBuilder(null, new Item[] {new Item("test", "type1", "1")}).minTermFreq(1).minDocFreq(1)).get();
assertHitCount(response, 2l);
logger.info("Running moreLikeThis on beta shard");
response = client().prepareSearch("beta").setQuery(
new MoreLikeThisQueryBuilder().like(new Item("test", "type1", "1")).minTermFreq(1).minDocFreq(1)).get();
new MoreLikeThisQueryBuilder(null, new Item[] {new Item("test", "type1", "1")}).minTermFreq(1).minDocFreq(1)).get();
assertHitCount(response, 1l);
assertThat(response.getHits().getAt(0).id(), equalTo("3"));
logger.info("Running moreLikeThis on release shard");
response = client().prepareSearch("release").setQuery(
new MoreLikeThisQueryBuilder().like(new Item("test", "type1", "1")).minTermFreq(1).minDocFreq(1)).get();
new MoreLikeThisQueryBuilder(null, new Item[] {new Item("test", "type1", "1")}).minTermFreq(1).minDocFreq(1)).get();
assertHitCount(response, 1l);
assertThat(response.getHits().getAt(0).id(), equalTo("2"));
logger.info("Running moreLikeThis on alias with node client");
response = internalCluster().clientNodeClient().prepareSearch("beta").setQuery(
new MoreLikeThisQueryBuilder().like(new Item("test", "type1", "1")).minTermFreq(1).minDocFreq(1)).get();
new MoreLikeThisQueryBuilder(null, new Item[] {new Item("test", "type1", "1")}).minTermFreq(1).minDocFreq(1)).get();
assertHitCount(response, 1l);
assertThat(response.getHits().getAt(0).id(), equalTo("3"));
}
@ -156,11 +157,11 @@ public class MoreLikeThisIT extends ESIntegTestCase {
assertThat(ensureGreen(), equalTo(ClusterHealthStatus.GREEN));
SearchResponse response = client().prepareSearch().setQuery(
new MoreLikeThisQueryBuilder().like(new Item("foo", "bar", "1"))).get();
new MoreLikeThisQueryBuilder(null, new Item[] {new Item("foo", "bar", "1")})).get();
assertNoFailures(response);
assertThat(response, notNullValue());
response = client().prepareSearch().setQuery(
new MoreLikeThisQueryBuilder().like(new Item("foo", "bar", "1"))).get();
new MoreLikeThisQueryBuilder(null, new Item[] {new Item("foo", "bar", "1")})).get();
assertNoFailures(response);
assertThat(response, notNullValue());
}
@ -182,7 +183,7 @@ public class MoreLikeThisIT extends ESIntegTestCase {
client().admin().indices().prepareRefresh("foo").execute().actionGet();
SearchResponse response = client().prepareSearch().setQuery(
new MoreLikeThisQueryBuilder().like(new Item("foo", "bar", "1").routing("2"))).get();
new MoreLikeThisQueryBuilder(null, new Item[] {new Item("foo", "bar", "1").routing("2")})).get();
assertNoFailures(response);
assertThat(response, notNullValue());
}
@ -205,7 +206,7 @@ public class MoreLikeThisIT extends ESIntegTestCase {
.execute().actionGet();
client().admin().indices().prepareRefresh("foo").execute().actionGet();
SearchResponse response = client().prepareSearch().setQuery(
new MoreLikeThisQueryBuilder().like(new Item("foo", "bar", "1").routing("4000"))).get();
new MoreLikeThisQueryBuilder(null, new Item[] {new Item("foo", "bar", "1").routing("4000")})).get();
assertNoFailures(response);
assertThat(response, notNullValue());
}
@ -233,41 +234,41 @@ public class MoreLikeThisIT extends ESIntegTestCase {
// Implicit list of fields -> ignore numeric fields
SearchResponse searchResponse = client().prepareSearch().setQuery(
new MoreLikeThisQueryBuilder().like(new Item("test", "type", "1")).minTermFreq(1).minDocFreq(1)).get();
new MoreLikeThisQueryBuilder(null, new Item[] {new Item("test", "type", "1")}).minTermFreq(1).minDocFreq(1)).get();
assertHitCount(searchResponse, 1l);
// Explicit list of fields including numeric fields -> fail
assertThrows(client().prepareSearch().setQuery(
new MoreLikeThisQueryBuilder("string_value", "int_value").like(new Item("test", "type", "1")).minTermFreq(1).minDocFreq(1)), SearchPhaseExecutionException.class);
new MoreLikeThisQueryBuilder(new String[] {"string_value", "int_value"}, null, new Item[] {new Item("test", "type", "1")}).minTermFreq(1).minDocFreq(1)), SearchPhaseExecutionException.class);
// mlt query with no field -> OK
searchResponse = client().prepareSearch().setQuery(moreLikeThisQuery().likeText("index").minTermFreq(1).minDocFreq(1)).execute().actionGet();
searchResponse = client().prepareSearch().setQuery(moreLikeThisQuery(new String[] {"index"}).minTermFreq(1).minDocFreq(1)).execute().actionGet();
assertHitCount(searchResponse, 2l);
// mlt query with string fields
searchResponse = client().prepareSearch().setQuery(moreLikeThisQuery("string_value").likeText("index").minTermFreq(1).minDocFreq(1)).execute().actionGet();
searchResponse = client().prepareSearch().setQuery(moreLikeThisQuery(new String[]{"string_value"}, new String[] {"index"}, null).minTermFreq(1).minDocFreq(1)).execute().actionGet();
assertHitCount(searchResponse, 2l);
// mlt query with at least a numeric field -> fail by default
assertThrows(client().prepareSearch().setQuery(moreLikeThisQuery("string_value", "int_value").likeText("index")), SearchPhaseExecutionException.class);
assertThrows(client().prepareSearch().setQuery(moreLikeThisQuery(new String[] {"string_value", "int_value"}, new String[] {"index"}, null)), SearchPhaseExecutionException.class);
// mlt query with at least a numeric field -> fail by command
assertThrows(client().prepareSearch().setQuery(moreLikeThisQuery("string_value", "int_value").likeText("index").failOnUnsupportedField(true)), SearchPhaseExecutionException.class);
assertThrows(client().prepareSearch().setQuery(moreLikeThisQuery(new String[] {"string_value", "int_value"}, new String[] {"index"}, null).failOnUnsupportedField(true)), SearchPhaseExecutionException.class);
// mlt query with at least a numeric field but fail_on_unsupported_field set to false
searchResponse = client().prepareSearch().setQuery(moreLikeThisQuery("string_value", "int_value").likeText("index").minTermFreq(1).minDocFreq(1).failOnUnsupportedField(false)).get();
searchResponse = client().prepareSearch().setQuery(moreLikeThisQuery(new String[] {"string_value", "int_value"}, new String[] {"index"}, null).minTermFreq(1).minDocFreq(1).failOnUnsupportedField(false)).get();
assertHitCount(searchResponse, 2l);
// mlt field query on a numeric field -> failure by default
assertThrows(client().prepareSearch().setQuery(moreLikeThisQuery("int_value").likeText("42").minTermFreq(1).minDocFreq(1)), SearchPhaseExecutionException.class);
assertThrows(client().prepareSearch().setQuery(moreLikeThisQuery(new String[] {"int_value"}, new String[] {"42"}, null).minTermFreq(1).minDocFreq(1)), SearchPhaseExecutionException.class);
// mlt field query on a numeric field -> failure by command
assertThrows(client().prepareSearch().setQuery(moreLikeThisQuery("int_value").likeText("42").minTermFreq(1).minDocFreq(1).failOnUnsupportedField(true)),
assertThrows(client().prepareSearch().setQuery(moreLikeThisQuery(new String[] {"int_value"}, new String[] {"42"}, null).minTermFreq(1).minDocFreq(1).failOnUnsupportedField(true)),
SearchPhaseExecutionException.class);
// mlt field query on a numeric field but fail_on_unsupported_field set to false
searchResponse = client().prepareSearch().setQuery(moreLikeThisQuery("int_value").likeText("42").minTermFreq(1).minDocFreq(1).failOnUnsupportedField(false)).execute().actionGet();
searchResponse = client().prepareSearch().setQuery(moreLikeThisQuery(new String[] {"int_value"}, new String[] {"42"}, null).minTermFreq(1).minDocFreq(1).failOnUnsupportedField(false)).execute().actionGet();
assertHitCount(searchResponse, 0l);
}
@ -295,16 +296,16 @@ public class MoreLikeThisIT extends ESIntegTestCase {
logger.info("Running More Like This with include true");
SearchResponse response = client().prepareSearch().setQuery(
new MoreLikeThisQueryBuilder().like(new Item("test", "type1", "1")).minTermFreq(1).minDocFreq(1).include(true).minimumShouldMatch("0%")).get();
new MoreLikeThisQueryBuilder(null, new Item[] {new Item("test", "type1", "1")}).minTermFreq(1).minDocFreq(1).include(true).minimumShouldMatch("0%")).get();
assertOrderedSearchHits(response, "1", "2");
response = client().prepareSearch().setQuery(
new MoreLikeThisQueryBuilder().like(new Item("test", "type1", "2")).minTermFreq(1).minDocFreq(1).include(true).minimumShouldMatch("0%")).get();
new MoreLikeThisQueryBuilder(null, new Item[] {new Item("test", "type1", "2")}).minTermFreq(1).minDocFreq(1).include(true).minimumShouldMatch("0%")).get();
assertOrderedSearchHits(response, "2", "1");
logger.info("Running More Like This with include false");
response = client().prepareSearch().setQuery(
new MoreLikeThisQueryBuilder().like(new Item("test", "type1", "1")).minTermFreq(1).minDocFreq(1).minimumShouldMatch("0%")).get();
new MoreLikeThisQueryBuilder(null, new Item[] {new Item("test", "type1", "1")}).minTermFreq(1).minDocFreq(1).minimumShouldMatch("0%")).get();
assertSearchHits(response, "2");
}
@ -326,7 +327,7 @@ public class MoreLikeThisIT extends ESIntegTestCase {
indexRandom(true, builders);
logger.info("Running MoreLikeThis");
MoreLikeThisQueryBuilder queryBuilder = QueryBuilders.moreLikeThisQuery("text").ids("1").include(true).minTermFreq(1).minDocFreq(1);
MoreLikeThisQueryBuilder queryBuilder = QueryBuilders.moreLikeThisQuery(new String[] {"text"}, null, ids("1")).include(true).minTermFreq(1).minDocFreq(1);
SearchResponse mltResponse = client().prepareSearch().setTypes("type1").setQuery(queryBuilder).execute().actionGet();
assertHitCount(mltResponse, 3l);
}
@ -354,8 +355,7 @@ public class MoreLikeThisIT extends ESIntegTestCase {
indexRandom(true, builders);
logger.info("Running MoreLikeThis");
MoreLikeThisQueryBuilder queryBuilder = QueryBuilders.moreLikeThisQuery("text").include(true).minTermFreq(1).minDocFreq(1)
.like(new Item("test", "type0", "0"));
MoreLikeThisQueryBuilder queryBuilder = QueryBuilders.moreLikeThisQuery(new String[] {"text"}, null, new Item[] {new Item("test", "type0", "0")}).include(true).minTermFreq(1).minDocFreq(1);
String[] types = new String[numOfTypes];
for (int i = 0; i < numOfTypes; i++) {
@ -388,7 +388,8 @@ public class MoreLikeThisIT extends ESIntegTestCase {
for (int i = 0; i < maxIters; i++) {
int max_query_terms = randomIntBetween(1, values.length);
logger.info("Running More Like This with max_query_terms = %s", max_query_terms);
MoreLikeThisQueryBuilder mltQuery = moreLikeThisQuery("text").ids("0").minTermFreq(1).minDocFreq(1)
MoreLikeThisQueryBuilder mltQuery = moreLikeThisQuery(new String[] {"text"}, null, new Item[] {new Item(null, null, "0")})
.minTermFreq(1).minDocFreq(1)
.maxQueryTerms(max_query_terms).minimumShouldMatch("0%");
SearchResponse response = client().prepareSearch("test").setTypes("type1")
.setQuery(mltQuery).execute().actionGet();
@ -419,8 +420,7 @@ public class MoreLikeThisIT extends ESIntegTestCase {
logger.info("Testing each minimum_should_match from 0% - 100% with 10% increment ...");
for (int i = 0; i <= 10; i++) {
String minimumShouldMatch = (10 * i) + "%";
MoreLikeThisQueryBuilder mltQuery = moreLikeThisQuery("text")
.likeText("1 2 3 4 5 6 7 8 9 10")
MoreLikeThisQueryBuilder mltQuery = moreLikeThisQuery(new String[] {"text"}, new String[] {"1 2 3 4 5 6 7 8 9 10"}, null)
.minTermFreq(1)
.minDocFreq(1)
.minimumShouldMatch(minimumShouldMatch);
@ -452,8 +452,7 @@ public class MoreLikeThisIT extends ESIntegTestCase {
indexRandom(true, client().prepareIndex("test", "type1", "0").setSource(doc));
logger.info("Checking the document matches ...");
MoreLikeThisQueryBuilder mltQuery = moreLikeThisQuery()
.like(new Item("test", "type1", doc).routing("0")) // routing to ensure we hit the shard with the doc
MoreLikeThisQueryBuilder mltQuery = moreLikeThisQuery(new Item[] {new Item("test", "type1", doc).routing("0")}) // routing to ensure we hit the shard with the doc
.minTermFreq(0)
.minDocFreq(0)
.maxQueryTerms(100)
@ -484,8 +483,7 @@ public class MoreLikeThisIT extends ESIntegTestCase {
.field("text", "Hello World!")
.field("date", "this is not a date!")
.endObject();
MoreLikeThisQueryBuilder mltQuery = moreLikeThisQuery()
.like(new Item("test", "type1", malformedFieldDoc))
MoreLikeThisQueryBuilder mltQuery = moreLikeThisQuery(new Item[] {new Item("test", "type1", malformedFieldDoc)})
.minTermFreq(0)
.minDocFreq(0)
.minimumShouldMatch("0%");
@ -496,8 +494,7 @@ public class MoreLikeThisIT extends ESIntegTestCase {
logger.info("Checking with an empty document ...");
XContentBuilder emptyDoc = jsonBuilder().startObject().endObject();
mltQuery = moreLikeThisQuery()
.like(new Item("test", "type1", emptyDoc))
mltQuery = moreLikeThisQuery(null, new Item[] {new Item("test", "type1", emptyDoc)})
.minTermFreq(0)
.minDocFreq(0)
.minimumShouldMatch("0%");
@ -508,8 +505,7 @@ public class MoreLikeThisIT extends ESIntegTestCase {
logger.info("Checking when document is malformed ...");
XContentBuilder malformedDoc = jsonBuilder().startObject();
mltQuery = moreLikeThisQuery()
.like(new Item("test", "type1", malformedDoc))
mltQuery = moreLikeThisQuery(null, new Item[] {new Item("test", "type1", malformedDoc)})
.minTermFreq(0)
.minDocFreq(0)
.minimumShouldMatch("0%");
@ -524,8 +520,7 @@ public class MoreLikeThisIT extends ESIntegTestCase {
.field("text", "Hello World!")
.field("date", "1000-01-01") // should be properly parsed but ignored ...
.endObject();
mltQuery = moreLikeThisQuery()
.like(new Item("test", "type1", normalDoc))
mltQuery = moreLikeThisQuery(null, new Item[] {new Item("test", "type1", normalDoc)})
.minTermFreq(0)
.minDocFreq(0)
.minimumShouldMatch("100%"); // strict all terms must match but date is ignored
@ -556,8 +551,7 @@ public class MoreLikeThisIT extends ESIntegTestCase {
indexRandom(true, builders);
logger.info("First check the document matches all indexed docs.");
MoreLikeThisQueryBuilder mltQuery = moreLikeThisQuery()
.like(new Item("test", "type1", doc))
MoreLikeThisQueryBuilder mltQuery = moreLikeThisQuery(new Item[] {new Item("test", "type1", doc)})
.minTermFreq(0)
.minDocFreq(0)
.maxQueryTerms(100)
@ -568,12 +562,11 @@ public class MoreLikeThisIT extends ESIntegTestCase {
assertHitCount(response, numFields);
logger.info("Now check like this doc, but ignore one doc in the index, then two and so on...");
List<Item> docs = new ArrayList<>();
List<Item> docs = new ArrayList<>(numFields);
for (int i = 0; i < numFields; i++) {
docs.add(new Item("test", "type1", i+""));
mltQuery = moreLikeThisQuery()
.like(new Item("test", "type1", doc))
.unlike(docs.toArray(Item.EMPTY_ARRAY))
mltQuery = moreLikeThisQuery(null, new Item[] {new Item("test", "type1", doc)})
.unlike(docs.toArray(new Item[docs.size()]))
.minTermFreq(0)
.minDocFreq(0)
.maxQueryTerms(100)
@ -602,8 +595,7 @@ public class MoreLikeThisIT extends ESIntegTestCase {
.field("text1", "elasticsearch")
.endObject()));
MoreLikeThisQueryBuilder mltQuery = moreLikeThisQuery()
.like(new Item("test", "type1", "1"))
MoreLikeThisQueryBuilder mltQuery = moreLikeThisQuery(new Item[] {new Item("test", "type1", "1")})
.minTermFreq(0)
.minDocFreq(0)
.include(true)
@ -613,8 +605,7 @@ public class MoreLikeThisIT extends ESIntegTestCase {
assertSearchResponse(response);
assertHitCount(response, 2);
mltQuery = moreLikeThisQuery("text")
.like(new Item("test", "type1", "1"))
mltQuery = moreLikeThisQuery(new String[] {"text"}, null, new Item[] {new Item("test", "type1", "1")})
.minTermFreq(0)
.minDocFreq(0)
.include(true)

View File

@ -229,8 +229,8 @@ public class ContextAndHeaderTransportIT extends ESIntegTestCase {
.get();
transportClient().admin().indices().prepareRefresh(lookupIndex, queryIndex).get();
MoreLikeThisQueryBuilder moreLikeThisQueryBuilder = QueryBuilders.moreLikeThisQuery("name")
.like(new Item(lookupIndex, "type", "1"))
MoreLikeThisQueryBuilder moreLikeThisQueryBuilder = QueryBuilders.moreLikeThisQuery(new String[] {"name"}, null,
new Item[] {new Item(lookupIndex, "type", "1")})
.minTermFreq(1)
.minDocFreq(1);

View File

@ -19,7 +19,6 @@
package org.elasticsearch.validate;
import java.nio.charset.StandardCharsets;
import org.elasticsearch.action.admin.indices.alias.Alias;
import org.elasticsearch.action.admin.indices.validate.query.ValidateQueryResponse;
import org.elasticsearch.client.Client;
@ -28,6 +27,7 @@ import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.unit.Fuzziness;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.index.IndexNotFoundException;
import org.elasticsearch.index.query.MoreLikeThisQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.test.ESIntegTestCase;
@ -250,10 +250,10 @@ public class SimpleValidateQueryIT extends ESIntegTestCase {
containsString("field:jumps^0.75"), true);
// more like this queries
assertExplanation(QueryBuilders.moreLikeThisQuery("field").ids("1")
assertExplanation(QueryBuilders.moreLikeThisQuery(new String[] { "field" }, null, MoreLikeThisQueryBuilder.ids("1"))
.include(true).minTermFreq(1).minDocFreq(1).maxQueryTerms(2),
containsString("field:huge field:pidgin"), true);
assertExplanation(QueryBuilders.moreLikeThisQuery("field").like("the huge pidgin")
assertExplanation(QueryBuilders.moreLikeThisQuery(new String[] { "field" }, new String[] {"the huge pidgin"}, null)
.minTermFreq(1).minDocFreq(1).maxQueryTerms(2),
containsString("field:huge field:pidgin"), true);
}

View File

@ -109,8 +109,11 @@ Also reusing new Operator enum.
Removed `MoreLikeThisQueryBuilder.Item#id(String id)`, `Item#doc(BytesReference doc)`,
`Item#doc(XContentBuilder doc)`. Use provided constructors instead.
Removed `MoreLikeThisQueryBuilder#addLike` and `addUnlike` in favor to using the `like`
and `unlike` methods.
Removed `MoreLikeThisQueryBuilder#addLike` in favor of texts and/or items beeing provided
at construction time. Using arrays there instead of lists now.
Removed `MoreLikeThisQueryBuilder#addUnlike` in favor to using the `unlike` methods
which take arrays as arguments now rather than the lists used before.
The deprecated `docs(Item... docs)`, `ignoreLike(Item... docs)`,
`ignoreLike(String... likeText)`, `addItem(Item... likeItems)` have been removed.