Search Fields: If a field is not stored, automatically extract it from _source (without the need for _source prefix), closes #562.

This commit is contained in:
kimchy 2010-12-12 05:00:24 +02:00
parent 216b2ab912
commit bc04243a2b
2 changed files with 20 additions and 2 deletions

View File

@ -20,6 +20,7 @@
package org.elasticsearch.search.fetch; package org.elasticsearch.search.fetch;
import org.elasticsearch.common.xcontent.XContentParser; import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.index.mapper.FieldMapper;
import org.elasticsearch.script.search.SearchScript; import org.elasticsearch.script.search.SearchScript;
import org.elasticsearch.search.SearchParseElement; import org.elasticsearch.search.SearchParseElement;
import org.elasticsearch.search.fetch.script.ScriptFieldsContext; import org.elasticsearch.search.fetch.script.ScriptFieldsContext;
@ -42,7 +43,14 @@ public class FieldsParseElement implements SearchParseElement {
SearchScript searchScript = new SearchScript(context.lookup(), null, name, null, context.scriptService()); SearchScript searchScript = new SearchScript(context.lookup(), null, name, null, context.scriptService());
context.scriptFields().add(new ScriptFieldsContext.ScriptField(name, searchScript)); context.scriptFields().add(new ScriptFieldsContext.ScriptField(name, searchScript));
} else { } else {
context.fieldNames().add(name); FieldMapper fieldMapper = context.mapperService().smartNameFieldMapper(name);
if (!"*".equals(name) && (fieldMapper == null || !fieldMapper.stored())) {
// script field to load from source
SearchScript searchScript = new SearchScript(context.lookup(), null, "_source." + name, null, context.scriptService());
context.scriptFields().add(new ScriptFieldsContext.ScriptField(name, searchScript));
} else {
context.fieldNames().add(name);
}
} }
} }
if (!added) { if (!added) {
@ -55,7 +63,14 @@ public class FieldsParseElement implements SearchParseElement {
SearchScript searchScript = new SearchScript(context.lookup(), null, name, null, context.scriptService()); SearchScript searchScript = new SearchScript(context.lookup(), null, name, null, context.scriptService());
context.scriptFields().add(new ScriptFieldsContext.ScriptField(name, searchScript)); context.scriptFields().add(new ScriptFieldsContext.ScriptField(name, searchScript));
} else { } else {
context.fieldNames().add(name); FieldMapper fieldMapper = context.mapperService().smartNameFieldMapper(name);
if (!"*".equals(name) && (fieldMapper == null || !fieldMapper.stored())) {
// script field to load from source
SearchScript searchScript = new SearchScript(context.lookup(), null, "_source." + name, null, context.scriptService());
context.scriptFields().add(new ScriptFieldsContext.ScriptField(name, searchScript));
} else {
context.fieldNames().add(name);
}
} }
} }
} }

View File

@ -82,9 +82,12 @@ public class SearchFieldsTests extends AbstractNodesTests {
assertThat(searchResponse.hits().getAt(0).fields().size(), equalTo(1)); assertThat(searchResponse.hits().getAt(0).fields().size(), equalTo(1));
assertThat(searchResponse.hits().getAt(0).fields().get("field1").value().toString(), equalTo("value1")); assertThat(searchResponse.hits().getAt(0).fields().get("field1").value().toString(), equalTo("value1"));
// field2 is not stored, check that it gets extracted from source
searchResponse = client.prepareSearch().setQuery(matchAllQuery()).addField("field2").execute().actionGet(); searchResponse = client.prepareSearch().setQuery(matchAllQuery()).addField("field2").execute().actionGet();
assertThat(searchResponse.hits().getTotalHits(), equalTo(1l)); assertThat(searchResponse.hits().getTotalHits(), equalTo(1l));
assertThat(searchResponse.hits().hits().length, equalTo(1)); assertThat(searchResponse.hits().hits().length, equalTo(1));
assertThat(searchResponse.hits().getAt(0).fields().size(), equalTo(1));
assertThat(searchResponse.hits().getAt(0).fields().get("field2").value().toString(), equalTo("value2"));
searchResponse = client.prepareSearch().setQuery(matchAllQuery()).addField("field3").execute().actionGet(); searchResponse = client.prepareSearch().setQuery(matchAllQuery()).addField("field3").execute().actionGet();
assertThat(searchResponse.hits().getTotalHits(), equalTo(1l)); assertThat(searchResponse.hits().getTotalHits(), equalTo(1l));