private void executeFetchPhase() { sortedShardList = searchPhaseController.sortDocs(queryResults.values()); Map<SearchShardTarget, ExtTIntArrayList> docIdsToLoad = searchPhaseController.docIdsToLoad(sortedShardList); if (docIdsToLoad.isEmpty()) { finishHim(); } final AtomicInteger counter = new AtomicInteger(docIdsToLoad.size()); for (final Map.Entry<SearchShardTarget, ExtTIntArrayList> entry : docIdsToLoad.entrySet()) { SearchShardTarget shardTarget = entry.getKey(); ExtTIntArrayList docIds = entry.getValue(); FetchSearchRequest fetchSearchRequest = new FetchSearchRequest(request, queryResults.get(shardTarget).id(), docIds); DiscoveryNode node = nodes.get(shardTarget.nodeId()); searchService.sendExecuteFetch( node, fetchSearchRequest, new SearchServiceListener<FetchSearchResult>() { @Override public void onResult(FetchSearchResult result) { result.shardTarget(entry.getKey()); fetchResults.put(result.shardTarget(), result); if (counter.decrementAndGet() == 0) { finishHim(); } } @Override public void onFailure(Throwable t) { if (logger.isDebugEnabled()) { logger.debug("Failed to execute fetch phase", t); } successfulOps.decrementAndGet(); if (counter.decrementAndGet() == 0) { finishHim(); } } }); } }
public void writeTo(StreamOutput out, InternalSearchHits.StreamContext context) throws IOException { out.writeFloat(score); out.writeText(id); out.writeText(type); out.writeOptionalStreamable(nestedIdentity); out.writeLong(version); out.writeBytesReference(source); if (explanation == null) { out.writeBoolean(false); } else { out.writeBoolean(true); writeExplanation(out, explanation); } if (fields == null) { out.writeVInt(0); } else { out.writeVInt(fields.size()); for (SearchHitField hitField : fields().values()) { hitField.writeTo(out); } } if (highlightFields == null) { out.writeVInt(0); } else { out.writeVInt(highlightFields.size()); for (HighlightField highlightField : highlightFields.values()) { highlightField.writeTo(out); } } if (sortValues.length == 0) { out.writeVInt(0); } else { out.writeVInt(sortValues.length); for (Object sortValue : sortValues) { if (sortValue == null) { out.writeByte((byte) 0); } else { Class type = sortValue.getClass(); if (type == String.class) { out.writeByte((byte) 1); out.writeString((String) sortValue); } else if (type == Integer.class) { out.writeByte((byte) 2); out.writeInt((Integer) sortValue); } else if (type == Long.class) { out.writeByte((byte) 3); out.writeLong((Long) sortValue); } else if (type == Float.class) { out.writeByte((byte) 4); out.writeFloat((Float) sortValue); } else if (type == Double.class) { out.writeByte((byte) 5); out.writeDouble((Double) sortValue); } else if (type == Byte.class) { out.writeByte((byte) 6); out.writeByte((Byte) sortValue); } else if (type == Short.class) { out.writeByte((byte) 7); out.writeShort((Short) sortValue); } else if (type == Boolean.class) { out.writeByte((byte) 8); out.writeBoolean((Boolean) sortValue); } else if (sortValue instanceof Text) { out.writeByte((byte) 9); out.writeText((Text) sortValue); } else { throw new IOException("Can't handle sort field value of type [" + type + "]"); } } } } if (matchedQueries.length == 0) { out.writeVInt(0); } else { out.writeVInt(matchedQueries.length); for (String matchedFilter : matchedQueries) { out.writeString(matchedFilter); } } if (context.streamShardTarget() == InternalSearchHits.StreamContext.ShardTargetType.STREAM) { if (shard == null) { out.writeBoolean(false); } else { out.writeBoolean(true); shard.writeTo(out); } } else if (context.streamShardTarget() == InternalSearchHits.StreamContext.ShardTargetType.LOOKUP) { if (shard == null) { out.writeVInt(0); } else { out.writeVInt(context.shardHandleLookup().get(shard)); } } if (innerHits == null) { out.writeVInt(0); } else { out.writeVInt(innerHits.size()); for (Map.Entry<String, InternalSearchHits> entry : innerHits.entrySet()) { out.writeString(entry.getKey()); entry .getValue() .writeTo( out, InternalSearchHits.streamContext() .streamShardTarget(InternalSearchHits.StreamContext.ShardTargetType.NO_STREAM)); } } }
@Override public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { List<SearchHitField> metaFields = Lists.newArrayList(); List<SearchHitField> otherFields = Lists.newArrayList(); if (fields != null && !fields.isEmpty()) { for (SearchHitField field : fields.values()) { if (field.values().isEmpty()) { continue; } if (field.isMetadataField()) { metaFields.add(field); } else { otherFields.add(field); } } } builder.startObject(); // For inner_hit hits shard is null and that is ok, because the parent search hit has all this // information. // Even if this was included in the inner_hit hits this would be the same, so better leave it // out. if (explanation() != null && shard != null) { builder.field("_shard", shard.shardId()); builder.field("_node", shard.nodeIdText()); } if (shard != null) { builder.field(Fields._INDEX, shard.indexText()); } builder.field(Fields._TYPE, type); builder.field(Fields._ID, id); if (nestedIdentity != null) { nestedIdentity.toXContent(builder, params); } if (version != -1) { builder.field(Fields._VERSION, version); } if (Float.isNaN(score)) { builder.nullField(Fields._SCORE); } else { builder.field(Fields._SCORE, score); } for (SearchHitField field : metaFields) { builder.field(field.name(), field.value()); } if (source != null) { XContentHelper.writeRawField("_source", source, builder, params); } if (!otherFields.isEmpty()) { builder.startObject(Fields.FIELDS); for (SearchHitField field : otherFields) { builder.startArray(field.name()); for (Object value : field.getValues()) { builder.value(value); } builder.endArray(); } builder.endObject(); } if (highlightFields != null && !highlightFields.isEmpty()) { builder.startObject(Fields.HIGHLIGHT); for (HighlightField field : highlightFields.values()) { builder.field(field.name()); if (field.fragments() == null) { builder.nullValue(); } else { builder.startArray(); for (Text fragment : field.fragments()) { builder.value(fragment); } builder.endArray(); } } builder.endObject(); } if (sortValues != null && sortValues.length > 0) { builder.startArray(Fields.SORT); for (Object sortValue : sortValues) { if (sortValue != null && sortValue.equals(MAX_TERM_AS_TEXT)) { // We don't display MAX_TERM in JSON responses in case some clients have UTF-8 parsers // that wouldn't accept a // non-character in the response, even though this is valid UTF-8 builder.nullValue(); } else { builder.value(sortValue); } } builder.endArray(); } if (matchedQueries.length > 0) { builder.startArray(Fields.MATCHED_QUERIES); for (String matchedFilter : matchedQueries) { builder.value(matchedFilter); } builder.endArray(); } if (explanation() != null) { builder.field(Fields._EXPLANATION); buildExplanation(builder, explanation()); } if (innerHits != null) { builder.startObject(Fields.INNER_HITS); for (Map.Entry<String, InternalSearchHits> entry : innerHits.entrySet()) { builder.startObject(entry.getKey()); entry.getValue().toXContent(builder, params); builder.endObject(); } builder.endObject(); } builder.endObject(); return builder; }
@Override public String index() { return shard.index(); }
@Override public void writeTo(StreamOutput out) throws IOException { super.writeTo(out); shardTarget.writeTo(out); result.writeTo(out); }