diff --git a/core/src/main/java/org/elasticsearch/common/lucene/search/MoreLikeThisQuery.java b/core/src/main/java/org/elasticsearch/common/lucene/search/MoreLikeThisQuery.java index cdfa9ad9991..410796497d5 100644 --- a/core/src/main/java/org/elasticsearch/common/lucene/search/MoreLikeThisQuery.java +++ b/core/src/main/java/org/elasticsearch/common/lucene/search/MoreLikeThisQuery.java @@ -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 unlikeText) { - this.unlikeText = unlikeText.toArray(Strings.EMPTY_ARRAY); + public void setUnlikeText(String[] unlikeText) { + this.unlikeText = unlikeText; } public String[] getMoreLikeFields() { diff --git a/core/src/main/java/org/elasticsearch/index/query/MoreLikeThisQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/MoreLikeThisQueryBuilder.java index bd43475c296..f777654195a 100644 --- a/core/src/main/java/org/elasticsearch/index/query/MoreLikeThisQueryBuilder.java +++ b/core/src/main/java/org/elasticsearch/index/query/MoreLikeThisQueryBuilder.java @@ -75,11 +75,11 @@ public class MoreLikeThisQueryBuilder extends AbstractQueryBuilder fields; - private List likeTexts = new ArrayList<>(); - private List unlikeTexts = new ArrayList<>(); - private List likeItems = new ArrayList<>(); - private List 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 fields) { - this.fields = fields; - } - - public List 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 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 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 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 unlikeItems() { + public Item[] unlikeItems() { return unlikeItems; } @@ -685,20 +669,18 @@ public class MoreLikeThisQueryBuilder extends AbstractQueryBuilder texts, List 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 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 likeItems, List unlikeItems, + private Query handleItems(QueryShardContext context, MoreLikeThisQuery mltQuery, Item[] likeItems, Item[] unlikeItems, boolean include, List 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 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 likeItems, @Nullable List 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 items) throws IOException { + private static Fields[] getFieldsFor(MultiTermVectorsResponse responses, Item[] items) throws IOException { List likeFields = new ArrayList<>(); Set selectedItems = new HashSet<>(); @@ -928,7 +908,7 @@ public class MoreLikeThisQueryBuilder extends AbstractQueryBuilder likeItems) { + private static void handleExclude(BooleanQuery boolQuery, Item[] likeItems) { // artificial docs get assigned a random id and should be disregarded List uids = new ArrayList<>(); for (Item item : likeItems) { @@ -943,23 +923,13 @@ public class MoreLikeThisQueryBuilder extends AbstractQueryBuilder) in.readGenericValue()); - moreLikeThisQueryBuilder.likeTexts = (List) in.readGenericValue(); - moreLikeThisQueryBuilder.unlikeTexts = (List) 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 readItems(StreamInput in) throws IOException { - List 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 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 { private static String[] randomFields; @@ -133,17 +134,20 @@ public class MoreLikeThisQueryBuilderTests extends AbstractQueryTestCase 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 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()); diff --git a/core/src/test/java/org/elasticsearch/index/query/SimpleIndexQueryParserTests.java b/core/src/test/java/org/elasticsearch/index/query/SimpleIndexQueryParserTests.java index dac1247160b..8d99d3d093b 100644 --- a/core/src/test/java/org/elasticsearch/index/query/SimpleIndexQueryParserTests.java +++ b/core/src/test/java/org/elasticsearch/index/query/SimpleIndexQueryParserTests.java @@ -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")); diff --git a/core/src/test/java/org/elasticsearch/search/morelikethis/MoreLikeThisIT.java b/core/src/test/java/org/elasticsearch/search/morelikethis/MoreLikeThisIT.java index dc98d0d9312..0e7001555fe 100644 --- a/core/src/test/java/org/elasticsearch/search/morelikethis/MoreLikeThisIT.java +++ b/core/src/test/java/org/elasticsearch/search/morelikethis/MoreLikeThisIT.java @@ -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 docs = new ArrayList<>(); + List 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) diff --git a/core/src/test/java/org/elasticsearch/transport/ContextAndHeaderTransportIT.java b/core/src/test/java/org/elasticsearch/transport/ContextAndHeaderTransportIT.java index 04e41548b99..abd0a063c90 100644 --- a/core/src/test/java/org/elasticsearch/transport/ContextAndHeaderTransportIT.java +++ b/core/src/test/java/org/elasticsearch/transport/ContextAndHeaderTransportIT.java @@ -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); diff --git a/core/src/test/java/org/elasticsearch/validate/SimpleValidateQueryIT.java b/core/src/test/java/org/elasticsearch/validate/SimpleValidateQueryIT.java index 505d41623ff..22c959f5cd0 100644 --- a/core/src/test/java/org/elasticsearch/validate/SimpleValidateQueryIT.java +++ b/core/src/test/java/org/elasticsearch/validate/SimpleValidateQueryIT.java @@ -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); } diff --git a/docs/reference/migration/migrate_query_refactoring.asciidoc b/docs/reference/migration/migrate_query_refactoring.asciidoc index d69e6c7542a..520a5fa2994 100644 --- a/docs/reference/migration/migrate_query_refactoring.asciidoc +++ b/docs/reference/migration/migrate_query_refactoring.asciidoc @@ -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.