@Override protected Query doToQuery(QueryShardContext context) throws IOException { DocumentMapper childDocMapper = context.getMapperService().documentMapper(type); if (childDocMapper == null) { if (ignoreUnmapped) { return new MatchNoDocsQuery(); } else { throw new QueryShardException( context, "[" + NAME + "] no mapping found for type [" + type + "]"); } } ParentFieldMapper parentFieldMapper = childDocMapper.parentFieldMapper(); if (parentFieldMapper.active() == false) { throw new QueryShardException( context, "[" + NAME + "] _parent field has no parent type configured"); } String fieldName = ParentFieldMapper.joinField(parentFieldMapper.type()); BooleanQuery.Builder query = new BooleanQuery.Builder(); query.add(new DocValuesTermsQuery(fieldName, id), BooleanClause.Occur.MUST); // Need to take child type into account, otherwise a child doc of different type with the same // id could match query.add(new TermQuery(new Term(TypeFieldMapper.NAME, type)), BooleanClause.Occur.FILTER); return query.build(); }
@Override protected Query doToQuery(QueryShardContext context) throws IOException { Query innerQuery; String[] previousTypes = context.getTypes(); context.setTypes(type); try { innerQuery = query.toQuery(context); } finally { context.setTypes(previousTypes); } DocumentMapper parentDocMapper = context.getMapperService().documentMapper(type); if (parentDocMapper == null) { if (ignoreUnmapped) { return new MatchNoDocsQuery(); } else { throw new QueryShardException( context, "[" + NAME + "] query configured 'parent_type' [" + type + "] is not a valid type"); } } Set<String> childTypes = new HashSet<>(); ParentChildIndexFieldData parentChildIndexFieldData = null; for (DocumentMapper documentMapper : context.getMapperService().docMappers(false)) { ParentFieldMapper parentFieldMapper = documentMapper.parentFieldMapper(); if (parentFieldMapper.active() && type.equals(parentFieldMapper.type())) { childTypes.add(documentMapper.type()); parentChildIndexFieldData = context.getForField(parentFieldMapper.fieldType()); } } if (childTypes.isEmpty()) { throw new QueryShardException( context, "[" + NAME + "] no child types found for type [" + type + "]"); } Query childrenQuery; if (childTypes.size() == 1) { DocumentMapper documentMapper = context.getMapperService().documentMapper(childTypes.iterator().next()); childrenQuery = documentMapper.typeFilter(); } else { BooleanQuery.Builder childrenFilter = new BooleanQuery.Builder(); for (String childrenTypeStr : childTypes) { DocumentMapper documentMapper = context.getMapperService().documentMapper(childrenTypeStr); childrenFilter.add(documentMapper.typeFilter(), BooleanClause.Occur.SHOULD); } childrenQuery = childrenFilter.build(); } // wrap the query with type query innerQuery = Queries.filtered(innerQuery, parentDocMapper.typeFilter()); return new HasChildQueryBuilder.LateParsingQuery( childrenQuery, innerQuery, HasChildQueryBuilder.DEFAULT_MIN_CHILDREN, HasChildQueryBuilder.DEFAULT_MAX_CHILDREN, type, score ? ScoreMode.Max : ScoreMode.None, parentChildIndexFieldData, context.getSearchSimilarity()); }