Skip to content

Commit

Permalink
inner hits: Don't fail if an object is specified as a nested value in…
Browse files Browse the repository at this point in the history
…stead of an array.

Closes #9723
  • Loading branch information
martijnvg committed Feb 19, 2015
1 parent b6c7988 commit 7cd9ffb
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 1 deletion.
13 changes: 12 additions & 1 deletion src/main/java/org/elasticsearch/search/fetch/FetchPhase.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,14 @@

package org.elasticsearch.search.fetch;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import org.apache.lucene.index.AtomicReaderContext;
import org.apache.lucene.index.ReaderUtil;
import org.apache.lucene.search.Filter;
import org.apache.lucene.util.FixedBitSet;
import org.elasticsearch.ElasticsearchIllegalArgumentException;
import org.elasticsearch.ElasticsearchIllegalStateException;
import org.elasticsearch.ExceptionsHelper;
import org.elasticsearch.common.bytes.BytesReference;
import org.elasticsearch.common.collect.Tuple;
Expand Down Expand Up @@ -291,7 +293,16 @@ private InternalSearchHit createNestedSearchHit(SearchContext context, int neste
List<Map<String, Object>> nestedParsedSource;
SearchHit.NestedIdentity nested = nestedIdentity;
do {
nestedParsedSource = (List<Map<String, Object>>) XContentMapValues.extractValue(nested.getField().string(), sourceAsMap);
Object extractedValue = XContentMapValues.extractValue(nested.getField().string(), sourceAsMap);
if (extractedValue instanceof List) {
// nested field has an array value in the _source
nestedParsedSource = (List<Map<String, Object>>) extractedValue;
} else if (extractedValue instanceof Map) {
// nested field has an object value in the _source. This just means the nested field has just one inner object, which is valid, but uncommon.
nestedParsedSource = ImmutableList.of((Map < String, Object >) extractedValue);
} else {
throw new ElasticsearchIllegalStateException("extracted source isn't an object or an array");
}
sourceAsMap = nestedParsedSource.get(nested.getOffset());
nested = nested.getChild();
} while (nested != null);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -645,4 +645,29 @@ public void testNestedMultipleLayers() throws Exception {
assertThat(innerHits.getAt(0).getNestedIdentity().getChild().getOffset(), equalTo(0));
}

@Test
// https://github.com/elasticsearch/elasticsearch/issues/9723
public void testNestedDefinedAsObject() throws Exception {
assertAcked(prepareCreate("articles").addMapping("article", "comments", "type=nested", "title", "type=string"));

List<IndexRequestBuilder> requests = new ArrayList<>();
requests.add(client().prepareIndex("articles", "article", "1").setSource(jsonBuilder().startObject()
.field("title", "quick brown fox")
.startObject("comments").field("message", "fox eat quick").endObject()
.endObject()));
indexRandom(true, requests);

SearchResponse response = client().prepareSearch("articles")
.setQuery(nestedQuery("comments", matchQuery("comments.message", "fox")).innerHit(new QueryInnerHitBuilder()))
.get();
assertNoFailures(response);
assertHitCount(response, 1);
assertThat(response.getHits().getAt(0).id(), equalTo("1"));
assertThat(response.getHits().getAt(0).getInnerHits().get("comments").getTotalHits(), equalTo(1l));
assertThat(response.getHits().getAt(0).getInnerHits().get("comments").getAt(0).id(), equalTo("1"));
assertThat(response.getHits().getAt(0).getInnerHits().get("comments").getAt(0).getNestedIdentity().getField().string(), equalTo("comments"));
assertThat(response.getHits().getAt(0).getInnerHits().get("comments").getAt(0).getNestedIdentity().getOffset(), equalTo(0));
assertThat(response.getHits().getAt(0).getInnerHits().get("comments").getAt(0).getNestedIdentity().getChild(), nullValue());
}

}

0 comments on commit 7cd9ffb

Please sign in to comment.