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:
parent
7eedd84dc3
commit
dbb01f5b43
|
@ -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() {
|
||||
|
|
|
@ -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) &&
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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"));
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Reference in New Issue