use of org.elasticsearch.index.mapper.ObjectMapper in project elasticsearch by elastic.
the class SortBuilder method resolveNested.
protected static Nested resolveNested(QueryShardContext context, String nestedPath, QueryBuilder nestedFilter) throws IOException {
Nested nested = null;
if (nestedPath != null) {
BitSetProducer rootDocumentsFilter = context.bitsetFilter(Queries.newNonNestedFilter());
ObjectMapper nestedObjectMapper = context.getObjectMapper(nestedPath);
if (nestedObjectMapper == null) {
throw new QueryShardException(context, "[nested] failed to find nested object under path [" + nestedPath + "]");
}
if (!nestedObjectMapper.nested().isNested()) {
throw new QueryShardException(context, "[nested] nested object under path [" + nestedPath + "] is not of nested type");
}
Query innerDocumentsQuery;
if (nestedFilter != null) {
context.nestedScope().nextLevel(nestedObjectMapper);
innerDocumentsQuery = QueryBuilder.rewriteQuery(nestedFilter, context).toFilter(context);
context.nestedScope().previousLevel();
} else {
innerDocumentsQuery = nestedObjectMapper.nestedTypeFilter();
}
nested = new Nested(rootDocumentsFilter, innerDocumentsQuery);
}
return nested;
}
use of org.elasticsearch.index.mapper.ObjectMapper in project elasticsearch by elastic.
the class FetchPhase method createNestedSearchHit.
private SearchHit createNestedSearchHit(SearchContext context, int nestedTopDocId, int nestedSubDocId, int rootSubDocId, Set<String> fieldNames, List<String> fieldNamePatterns, LeafReaderContext subReaderContext) throws IOException {
// Also if highlighting is requested on nested documents we need to fetch the _source from the root document,
// otherwise highlighting will attempt to fetch the _source from the nested doc, which will fail,
// because the entire _source is only stored with the root document.
final FieldsVisitor rootFieldsVisitor = new FieldsVisitor(context.sourceRequested() || context.highlight() != null);
loadStoredFields(context, subReaderContext, rootFieldsVisitor, rootSubDocId);
rootFieldsVisitor.postProcess(context.mapperService());
Map<String, SearchHitField> searchFields = getSearchFields(context, nestedSubDocId, fieldNames, fieldNamePatterns, subReaderContext);
DocumentMapper documentMapper = context.mapperService().documentMapper(rootFieldsVisitor.uid().type());
SourceLookup sourceLookup = context.lookup().source();
sourceLookup.setSegmentAndDocument(subReaderContext, nestedSubDocId);
ObjectMapper nestedObjectMapper = documentMapper.findNestedObjectMapper(nestedSubDocId, context, subReaderContext);
assert nestedObjectMapper != null;
SearchHit.NestedIdentity nestedIdentity = getInternalNestedIdentity(context, nestedSubDocId, subReaderContext, documentMapper, nestedObjectMapper);
BytesReference source = rootFieldsVisitor.source();
if (source != null) {
Tuple<XContentType, Map<String, Object>> tuple = XContentHelper.convertToMap(source, true);
Map<String, Object> sourceAsMap = tuple.v2();
// Isolate the nested json array object that matches with nested hit and wrap it back into the same json
// structure with the nested json array object being the actual content. The latter is important, so that
// features like source filtering and highlighting work consistent regardless of whether the field points
// to a json object array for consistency reasons on how we refer to fields
Map<String, Object> nestedSourceAsMap = new HashMap<>();
Map<String, Object> current = nestedSourceAsMap;
for (SearchHit.NestedIdentity nested = nestedIdentity; nested != null; nested = nested.getChild()) {
String nestedPath = nested.getField().string();
current.put(nestedPath, new HashMap<>());
Object extractedValue = XContentMapValues.extractValue(nestedPath, sourceAsMap);
List<Map<String, Object>> nestedParsedSource;
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 = Collections.singletonList((Map<String, Object>) extractedValue);
} else {
throw new IllegalStateException("extracted source isn't an object or an array");
}
sourceAsMap = nestedParsedSource.get(nested.getOffset());
if (nested.getChild() == null) {
current.put(nestedPath, sourceAsMap);
} else {
Map<String, Object> next = new HashMap<>();
current.put(nestedPath, next);
current = next;
}
}
context.lookup().source().setSource(nestedSourceAsMap);
XContentType contentType = tuple.v1();
BytesReference nestedSource = contentBuilder(contentType).map(sourceAsMap).bytes();
context.lookup().source().setSource(nestedSource);
context.lookup().source().setSourceContentType(contentType);
}
return new SearchHit(nestedTopDocId, rootFieldsVisitor.uid().id(), documentMapper.typeText(), nestedIdentity, searchFields);
}
use of org.elasticsearch.index.mapper.ObjectMapper in project elasticsearch by elastic.
the class NestedQueryBuilder method doToQuery.
@Override
protected Query doToQuery(QueryShardContext context) throws IOException {
ObjectMapper nestedObjectMapper = context.getObjectMapper(path);
if (nestedObjectMapper == null) {
if (ignoreUnmapped) {
return new MatchNoDocsQuery();
} else {
throw new IllegalStateException("[" + NAME + "] failed to find nested object under path [" + path + "]");
}
}
if (!nestedObjectMapper.nested().isNested()) {
throw new IllegalStateException("[" + NAME + "] nested object under path [" + path + "] is not of nested type");
}
final BitSetProducer parentFilter;
Query innerQuery;
ObjectMapper objectMapper = context.nestedScope().getObjectMapper();
if (objectMapper == null) {
parentFilter = context.bitsetFilter(Queries.newNonNestedFilter());
} else {
parentFilter = context.bitsetFilter(objectMapper.nestedTypeFilter());
}
try {
context.nestedScope().nextLevel(nestedObjectMapper);
innerQuery = this.query.toQuery(context);
} finally {
context.nestedScope().previousLevel();
}
// in its child space
if (new NestedHelper(context.getMapperService()).mightMatchNonNestedDocs(innerQuery, path)) {
innerQuery = Queries.filtered(innerQuery, nestedObjectMapper.nestedTypeFilter());
}
return new ESToParentBlockJoinQuery(innerQuery, parentFilter, scoreMode, objectMapper == null ? null : objectMapper.fullPath());
}
use of org.elasticsearch.index.mapper.ObjectMapper in project elasticsearch by elastic.
the class NestedScope method nextLevel.
/**
* Sets the new current nested level and pushes old current nested level down the stack returns that level.
*/
public ObjectMapper nextLevel(ObjectMapper level) {
ObjectMapper previous = levelStack.peek();
levelStack.push(level);
return previous;
}
use of org.elasticsearch.index.mapper.ObjectMapper in project elasticsearch by elastic.
the class InnerHitBuilder method build.
public InnerHitsContext.BaseInnerHits build(SearchContext parentSearchContext, InnerHitsContext innerHitsContext) throws IOException {
QueryShardContext queryShardContext = parentSearchContext.getQueryShardContext();
if (nestedPath != null) {
ObjectMapper nestedObjectMapper = queryShardContext.getObjectMapper(nestedPath);
if (nestedObjectMapper == null) {
if (ignoreUnmapped == false) {
throw new IllegalStateException("[" + query.getName() + "] no mapping found for type [" + nestedPath + "]");
} else {
return null;
}
}
ObjectMapper parentObjectMapper = queryShardContext.nestedScope().nextLevel(nestedObjectMapper);
InnerHitsContext.NestedInnerHits nestedInnerHits = new InnerHitsContext.NestedInnerHits(name, parentSearchContext, parentObjectMapper, nestedObjectMapper);
setupInnerHitsContext(queryShardContext, nestedInnerHits);
if (childInnerHits != null) {
buildChildInnerHits(parentSearchContext, nestedInnerHits);
}
queryShardContext.nestedScope().previousLevel();
innerHitsContext.addInnerHitDefinition(nestedInnerHits);
return nestedInnerHits;
} else if (parentChildType != null) {
DocumentMapper documentMapper = queryShardContext.documentMapper(parentChildType);
if (documentMapper == null) {
if (ignoreUnmapped == false) {
throw new IllegalStateException("[" + query.getName() + "] no mapping found for type [" + parentChildType + "]");
} else {
return null;
}
}
InnerHitsContext.ParentChildInnerHits parentChildInnerHits = new InnerHitsContext.ParentChildInnerHits(name, parentSearchContext, queryShardContext.getMapperService(), documentMapper);
setupInnerHitsContext(queryShardContext, parentChildInnerHits);
if (childInnerHits != null) {
buildChildInnerHits(parentSearchContext, parentChildInnerHits);
}
innerHitsContext.addInnerHitDefinition(parentChildInnerHits);
return parentChildInnerHits;
} else {
throw new IllegalStateException("Neither a nested or parent/child inner hit");
}
}
Aggregations