Search: Remove partial fields.

Partial fields have been deprecated since 1.0.0Beta1 in favor of _source
filtering. They will be removed in 2.0.
This commit is contained in:
Adrien Grand 2014-10-17 13:24:04 +02:00
parent f4ee3f25e4
commit 230c6684a9
15 changed files with 11 additions and 434 deletions

View File

@ -10,3 +10,7 @@ The <<alias-retrieving, get alias api>> will, by default produce an error respon
if a requested index does not exist. This change brings the defaults for this API in
line with the other Indices APIs. The <<multi-index>> options can be used on a request
to change this behavior
=== Partial fields
Partial fields were deprecated since 1.0.0beta1 in favor of <<search-request-source-filtering,source filtering>>.

View File

@ -444,40 +444,6 @@ public class SearchRequestBuilder extends ActionRequestBuilder<SearchRequest, Se
return this;
}
/**
* Adds a partial field based on _source, with an "include" and/or "exclude" set which can include simple wildcard
* elements.
*
* @deprecated since 1.0.0
* use {@link org.elasticsearch.action.search.SearchRequestBuilder#setFetchSource(String, String)} instead
*
* @param name The name of the field
* @param include An optional include (optionally wildcarded) pattern from _source
* @param exclude An optional exclude (optionally wildcarded) pattern from _source
*/
@Deprecated
public SearchRequestBuilder addPartialField(String name, @Nullable String include, @Nullable String exclude) {
sourceBuilder().partialField(name, include, exclude);
return this;
}
/**
* Adds a partial field based on _source, with an "includes" and/or "excludes set which can include simple wildcard
* elements.
*
* @deprecated since 1.0.0
* use {@link org.elasticsearch.action.search.SearchRequestBuilder#setFetchSource(String[], String[])} instead
*
* @param name The name of the field
* @param includes An optional list of includes (optionally wildcarded) patterns from _source
* @param excludes An optional list of excludes (optionally wildcarded) patterns from _source
*/
@Deprecated
public SearchRequestBuilder addPartialField(String name, @Nullable String[] includes, @Nullable String[] excludes) {
sourceBuilder().partialField(name, includes, excludes);
return this;
}
/**
* Adds a script based field to load and return. The field does not have to be stored,
* but its recommended to use non analyzed or numeric fields.

View File

@ -55,7 +55,6 @@ import org.elasticsearch.search.dfs.DfsSearchResult;
import org.elasticsearch.search.fetch.FetchSearchResult;
import org.elasticsearch.search.fetch.FetchSubPhase;
import org.elasticsearch.search.fetch.fielddata.FieldDataFieldsContext;
import org.elasticsearch.search.fetch.partial.PartialFieldsContext;
import org.elasticsearch.search.fetch.script.ScriptFieldsContext;
import org.elasticsearch.search.fetch.source.FetchSourceContext;
import org.elasticsearch.search.highlight.SearchContextHighlight;
@ -379,16 +378,6 @@ public class PercolateContext extends SearchContext {
throw new UnsupportedOperationException();
}
@Override
public boolean hasPartialFields() {
throw new UnsupportedOperationException();
}
@Override
public PartialFieldsContext partialFields() {
throw new UnsupportedOperationException();
}
@Override
public boolean sourceRequested() {
throw new UnsupportedOperationException();

View File

@ -33,7 +33,6 @@ import org.elasticsearch.search.fetch.FetchPhase;
import org.elasticsearch.search.fetch.explain.ExplainFetchSubPhase;
import org.elasticsearch.search.fetch.fielddata.FieldDataFieldsFetchSubPhase;
import org.elasticsearch.search.fetch.matchedqueries.MatchedQueriesFetchSubPhase;
import org.elasticsearch.search.fetch.partial.PartialFieldsFetchSubPhase;
import org.elasticsearch.search.fetch.script.ScriptFieldsFetchSubPhase;
import org.elasticsearch.search.fetch.source.FetchSourceSubPhase;
import org.elasticsearch.search.fetch.version.VersionFetchSubPhase;
@ -63,7 +62,6 @@ public class SearchModule extends AbstractModule implements SpawnModules {
bind(ExplainFetchSubPhase.class).asEagerSingleton();
bind(FieldDataFieldsFetchSubPhase.class).asEagerSingleton();
bind(ScriptFieldsFetchSubPhase.class).asEagerSingleton();
bind(PartialFieldsFetchSubPhase.class).asEagerSingleton();
bind(FetchSourceSubPhase.class).asEagerSingleton();
bind(VersionFetchSubPhase.class).asEagerSingleton();
bind(MatchedQueriesFetchSubPhase.class).asEagerSingleton();

View File

@ -47,7 +47,6 @@ import org.elasticsearch.search.aggregations.SearchContextAggregations;
import org.elasticsearch.search.dfs.DfsSearchResult;
import org.elasticsearch.search.fetch.FetchSearchResult;
import org.elasticsearch.search.fetch.fielddata.FieldDataFieldsContext;
import org.elasticsearch.search.fetch.partial.PartialFieldsContext;
import org.elasticsearch.search.fetch.script.ScriptFieldsContext;
import org.elasticsearch.search.fetch.source.FetchSourceContext;
import org.elasticsearch.search.highlight.SearchContextHighlight;
@ -86,7 +85,6 @@ public class TopHitsContext extends SearchContext {
private List<String> fieldNames;
private FieldDataFieldsContext fieldDataFields;
private ScriptFieldsContext scriptFields;
private PartialFieldsContext partialFields;
private FetchSourceContext fetchSourceContext;
private SearchContextHighlight highlight;
@ -247,19 +245,6 @@ public class TopHitsContext extends SearchContext {
return this.scriptFields;
}
@Override
public boolean hasPartialFields() {
return partialFields != null;
}
@Override
public PartialFieldsContext partialFields() {
if (partialFields == null) {
partialFields = new PartialFieldsContext();
}
return this.partialFields;
}
@Override
public boolean sourceRequested() {
return fetchSourceContext != null && fetchSourceContext.fetchSource();

View File

@ -103,7 +103,6 @@ public class SearchSourceBuilder implements ToXContent {
private List<String> fieldNames;
private List<String> fieldDataFields;
private List<ScriptField> scriptFields;
private List<PartialField> partialFields;
private FetchSourceContext fetchSourceContext;
private List<AbstractAggregationBuilder> aggregations;
@ -592,46 +591,6 @@ public class SearchSourceBuilder implements ToXContent {
return this;
}
/**
* Adds a partial field based on _source, with an "include" and/or "exclude" set which can include simple wildcard
* elements.
*
* @deprecated since 1.0.0
* use {@link SearchSourceBuilder#fetchSource(String, String)} instead
*
* @param name The name of the field
* @param include An optional include (optionally wildcarded) pattern from _source
* @param exclude An optional exclude (optionally wildcarded) pattern from _source
*/
@Deprecated
public SearchSourceBuilder partialField(String name, @Nullable String include, @Nullable String exclude) {
if (partialFields == null) {
partialFields = Lists.newArrayList();
}
partialFields.add(new PartialField(name, include, exclude));
return this;
}
/**
* Adds a partial field based on _source, with an "includes" and/or "excludes set which can include simple wildcard
* elements.
*
* @deprecated since 1.0.0
* use {@link SearchSourceBuilder#fetchSource(String[], String[])} instead
*
* @param name The name of the field
* @param includes An optional list of includes (optionally wildcarded) patterns from _source
* @param excludes An optional list of excludes (optionally wildcarded) patterns from _source
*/
@Deprecated
public SearchSourceBuilder partialField(String name, @Nullable String[] includes, @Nullable String[] excludes) {
if (partialFields == null) {
partialFields = Lists.newArrayList();
}
partialFields.add(new PartialField(name, includes, excludes));
return this;
}
/**
* Sets the boost a specific index will receive when the query is executeed against it.
*
@ -768,29 +727,6 @@ public class SearchSourceBuilder implements ToXContent {
builder.endArray();
}
if (partialFields != null) {
builder.startObject("partial_fields");
for (PartialField partialField : partialFields) {
builder.startObject(partialField.name());
if (partialField.includes() != null) {
if (partialField.includes().length == 1) {
builder.field("include", partialField.includes()[0]);
} else {
builder.field("include", partialField.includes());
}
}
if (partialField.excludes() != null) {
if (partialField.excludes().length == 1) {
builder.field("exclude", partialField.excludes()[0]);
} else {
builder.field("exclude", partialField.excludes());
}
}
builder.endObject();
}
builder.endObject();
}
if (scriptFields != null) {
builder.startObject("script_fields");
for (ScriptField scriptField : scriptFields) {

View File

@ -47,7 +47,6 @@ import org.elasticsearch.search.SearchPhase;
import org.elasticsearch.search.fetch.explain.ExplainFetchSubPhase;
import org.elasticsearch.search.fetch.fielddata.FieldDataFieldsFetchSubPhase;
import org.elasticsearch.search.fetch.matchedqueries.MatchedQueriesFetchSubPhase;
import org.elasticsearch.search.fetch.partial.PartialFieldsFetchSubPhase;
import org.elasticsearch.search.fetch.script.ScriptFieldsFetchSubPhase;
import org.elasticsearch.search.fetch.source.FetchSourceContext;
import org.elasticsearch.search.fetch.source.FetchSourceSubPhase;
@ -72,10 +71,10 @@ public class FetchPhase implements SearchPhase {
private final FetchSubPhase[] fetchSubPhases;
@Inject
public FetchPhase(HighlightPhase highlightPhase, ScriptFieldsFetchSubPhase scriptFieldsPhase, PartialFieldsFetchSubPhase partialFieldsPhase,
public FetchPhase(HighlightPhase highlightPhase, ScriptFieldsFetchSubPhase scriptFieldsPhase,
MatchedQueriesFetchSubPhase matchedQueriesPhase, ExplainFetchSubPhase explainPhase, VersionFetchSubPhase versionPhase,
FetchSourceSubPhase fetchSourceSubPhase, FieldDataFieldsFetchSubPhase fieldDataFieldsFetchSubPhase) {
this.fetchSubPhases = new FetchSubPhase[]{scriptFieldsPhase, partialFieldsPhase, matchedQueriesPhase, explainPhase, highlightPhase,
this.fetchSubPhases = new FetchSubPhase[]{scriptFieldsPhase, matchedQueriesPhase, explainPhase, highlightPhase,
fetchSourceSubPhase, versionPhase, fieldDataFieldsFetchSubPhase};
}
@ -100,16 +99,11 @@ public class FetchPhase implements SearchPhase {
boolean loadAllStored = false;
if (!context.hasFieldNames()) {
if (context.hasPartialFields()) {
// partial fields need the source, so fetch it
fieldsVisitor = new UidAndSourceFieldsVisitor();
} else {
// no fields specified, default to return source if no explicit indication
if (!context.hasScriptFields() && !context.hasFetchSourceContext()) {
context.fetchSourceContext(new FetchSourceContext(true));
}
fieldsVisitor = context.sourceRequested() ? new UidAndSourceFieldsVisitor() : new JustUidFieldsVisitor();
}
} else if (context.fieldNames().isEmpty()) {
if (context.sourceRequested()) {
fieldsVisitor = new UidAndSourceFieldsVisitor();

View File

@ -1,67 +0,0 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.elasticsearch.search.fetch.partial;
import com.google.common.collect.Lists;
import java.util.List;
/**
*/
public class PartialFieldsContext {
public static class PartialField {
private final String name;
private final String[] includes;
private final String[] excludes;
public PartialField(String name, String[] includes, String[] excludes) {
this.name = name;
this.includes = includes;
this.excludes = excludes;
}
public String name() {
return this.name;
}
public String[] includes() {
return this.includes;
}
public String[] excludes() {
return this.excludes;
}
}
private final List<PartialField> fields = Lists.newArrayList();
public PartialFieldsContext() {
}
public void add(PartialField field) {
fields.add(field);
}
public List<PartialField> fields() {
return this.fields;
}
}

View File

@ -1,84 +0,0 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.elasticsearch.search.fetch.partial;
import com.google.common.collect.ImmutableMap;
import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.search.SearchHitField;
import org.elasticsearch.search.SearchParseElement;
import org.elasticsearch.search.fetch.FetchSubPhase;
import org.elasticsearch.search.internal.InternalSearchHit;
import org.elasticsearch.search.internal.InternalSearchHitField;
import org.elasticsearch.search.internal.SearchContext;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
/**
*/
public class PartialFieldsFetchSubPhase implements FetchSubPhase {
@Inject
public PartialFieldsFetchSubPhase() {
}
@Override
public Map<String, ? extends SearchParseElement> parseElements() {
ImmutableMap.Builder<String, SearchParseElement> parseElements = ImmutableMap.builder();
parseElements.put("partial_fields", new PartialFieldsParseElement())
.put("partialFields", new PartialFieldsParseElement());
return parseElements.build();
}
@Override
public boolean hitsExecutionNeeded(SearchContext context) {
return false;
}
@Override
public void hitsExecute(SearchContext context, InternalSearchHit[] hits) throws ElasticsearchException {
}
@Override
public boolean hitExecutionNeeded(SearchContext context) {
return context.hasPartialFields();
}
@Override
public void hitExecute(SearchContext context, HitContext hitContext) throws ElasticsearchException {
for (PartialFieldsContext.PartialField field : context.partialFields().fields()) {
Object value = context.lookup().source().filter(field.includes(), field.excludes());
if (hitContext.hit().fieldsOrNull() == null) {
hitContext.hit().fields(new HashMap<String, SearchHitField>(2));
}
SearchHitField hitField = hitContext.hit().fields().get(field.name());
if (hitField == null) {
hitField = new InternalSearchHitField(field.name(), new ArrayList<>(2));
hitContext.hit().fields().put(field.name(), hitField);
}
hitField.values().add(value);
}
}
}

View File

@ -1,95 +0,0 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.elasticsearch.search.fetch.partial;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.search.SearchParseElement;
import org.elasticsearch.search.internal.SearchContext;
import java.util.ArrayList;
import java.util.List;
/**
* <pre>
* "partial_fields" : {
* "test1" : {
* "includes" : "doc['field_name'].value"
* },
* "test2" : {
* "excludes" : "..."
* }
* }
* </pre>
*/
public class PartialFieldsParseElement implements SearchParseElement {
@Override
public void parse(XContentParser parser, SearchContext context) throws Exception {
XContentParser.Token token;
String currentFieldName = null;
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
if (token == XContentParser.Token.FIELD_NAME) {
currentFieldName = parser.currentName();
} else if (token == XContentParser.Token.START_OBJECT) {
String fieldName = currentFieldName;
List<String> includes = null;
List<String> excludes = null;
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
if (token == XContentParser.Token.FIELD_NAME) {
currentFieldName = parser.currentName();
} else if (token == XContentParser.Token.START_ARRAY) {
if ("includes".equals(currentFieldName) || "include".equals(currentFieldName)) {
if (includes == null) {
includes = new ArrayList<>(2);
}
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
includes.add(parser.text());
}
} else if ("excludes".equals(currentFieldName) || "exclude".equals(currentFieldName)) {
if (excludes == null) {
excludes = new ArrayList<>(2);
}
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
excludes.add(parser.text());
}
}
} else if (token.isValue()) {
if ("include".equals(currentFieldName)) {
if (includes == null) {
includes = new ArrayList<>(2);
}
includes.add(parser.text());
} else if ("exclude".equals(currentFieldName)) {
if (excludes == null) {
excludes = new ArrayList<>(2);
}
excludes.add(parser.text());
}
}
}
PartialFieldsContext.PartialField field = new PartialFieldsContext.PartialField(fieldName,
includes == null ? Strings.EMPTY_ARRAY : includes.toArray(new String[includes.size()]),
excludes == null ? Strings.EMPTY_ARRAY : excludes.toArray(new String[excludes.size()]));
context.partialFields().add(field);
}
}
}
}

View File

@ -59,7 +59,6 @@ import org.elasticsearch.search.aggregations.SearchContextAggregations;
import org.elasticsearch.search.dfs.DfsSearchResult;
import org.elasticsearch.search.fetch.FetchSearchResult;
import org.elasticsearch.search.fetch.fielddata.FieldDataFieldsContext;
import org.elasticsearch.search.fetch.partial.PartialFieldsContext;
import org.elasticsearch.search.fetch.script.ScriptFieldsContext;
import org.elasticsearch.search.fetch.source.FetchSourceContext;
import org.elasticsearch.search.highlight.SearchContextHighlight;
@ -131,7 +130,6 @@ public class DefaultSearchContext extends SearchContext {
private List<String> fieldNames;
private FieldDataFieldsContext fieldDataFields;
private ScriptFieldsContext scriptFields;
private PartialFieldsContext partialFields;
private FetchSourceContext fetchSourceContext;
private int from = -1;
@ -379,17 +377,6 @@ public class DefaultSearchContext extends SearchContext {
return this.scriptFields;
}
public boolean hasPartialFields() {
return partialFields != null;
}
public PartialFieldsContext partialFields() {
if (partialFields == null) {
partialFields = new PartialFieldsContext();
}
return this.partialFields;
}
/**
* A shortcut function to see whether there is a fetchSourceContext and it says the source is requested.
*

View File

@ -52,7 +52,6 @@ import org.elasticsearch.search.aggregations.SearchContextAggregations;
import org.elasticsearch.search.dfs.DfsSearchResult;
import org.elasticsearch.search.fetch.FetchSearchResult;
import org.elasticsearch.search.fetch.fielddata.FieldDataFieldsContext;
import org.elasticsearch.search.fetch.partial.PartialFieldsContext;
import org.elasticsearch.search.fetch.script.ScriptFieldsContext;
import org.elasticsearch.search.fetch.source.FetchSourceContext;
import org.elasticsearch.search.highlight.SearchContextHighlight;
@ -176,10 +175,6 @@ public abstract class SearchContext implements Releasable {
public abstract ScriptFieldsContext scriptFields();
public abstract boolean hasPartialFields();
public abstract PartialFieldsContext partialFields();
/**
* A shortcut function to see whether there is a fetchSourceContext and it says the source is requested.
*

View File

@ -317,23 +317,6 @@ public class SearchFieldsTests extends ElasticsearchIntegrationTest {
.execute().actionGet();
client().admin().indices().prepareRefresh().execute().actionGet();
SearchResponse response = client().prepareSearch("test")
.addPartialField("partial1", "obj1.arr1.*", null)
.addPartialField("partial2", null, "obj1")
.execute().actionGet();
assertThat("Failures " + Arrays.toString(response.getShardFailures()), response.getShardFailures().length, equalTo(0));
Map<String, Object> partial1 = response.getHits().getAt(0).field("partial1").value();
assertThat(partial1, notNullValue());
assertThat(partial1.containsKey("field1"), equalTo(false));
assertThat(partial1.containsKey("obj1"), equalTo(true));
assertThat(((Map) partial1.get("obj1")).get("arr1"), instanceOf(List.class));
Map<String, Object> partial2 = response.getHits().getAt(0).field("partial2").value();
assertThat(partial2, notNullValue());
assertThat(partial2.containsKey("obj1"), equalTo(false));
assertThat(partial2.containsKey("field1"), equalTo(true));
}
@Test

View File

@ -46,9 +46,6 @@ public class SourceFetchingTests extends ElasticsearchIntegrationTest {
response = client().prepareSearch("test").addField("_source").get();
assertThat(response.getHits().getAt(0).getSourceAsString(), notNullValue());
response = client().prepareSearch("test").addPartialField("test", "field", null).get();
assertThat(response.getHits().getAt(0).getSourceAsString(), nullValue());
}
@Test

View File

@ -47,7 +47,6 @@ import org.elasticsearch.search.aggregations.SearchContextAggregations;
import org.elasticsearch.search.dfs.DfsSearchResult;
import org.elasticsearch.search.fetch.FetchSearchResult;
import org.elasticsearch.search.fetch.fielddata.FieldDataFieldsContext;
import org.elasticsearch.search.fetch.partial.PartialFieldsContext;
import org.elasticsearch.search.fetch.script.ScriptFieldsContext;
import org.elasticsearch.search.fetch.source.FetchSourceContext;
import org.elasticsearch.search.highlight.SearchContextHighlight;
@ -238,16 +237,6 @@ public class TestSearchContext extends SearchContext {
return null;
}
@Override
public boolean hasPartialFields() {
return false;
}
@Override
public PartialFieldsContext partialFields() {
return null;
}
@Override
public boolean sourceRequested() {
return false;