Fixed unable to highlight on all multi-valued field values.

Closes #2384
This commit is contained in:
Martijn van Groningen 2012-12-03 12:17:51 +01:00
parent f17ad829ac
commit 6cfd938dce
3 changed files with 43 additions and 8 deletions

View File

@ -35,20 +35,20 @@ public abstract class AbstractFragmentsBuilder extends BaseFragmentsBuilder {
private boolean discreteMultiValueHighlighting = true; private boolean discreteMultiValueHighlighting = true;
protected AbstractFragmentsBuilder(){ protected AbstractFragmentsBuilder() {
super(); super();
} }
protected AbstractFragmentsBuilder(BoundaryScanner boundaryScanner){ protected AbstractFragmentsBuilder(BoundaryScanner boundaryScanner) {
super(boundaryScanner); super(boundaryScanner);
} }
protected AbstractFragmentsBuilder( String[] preTags, String[] postTags ){ protected AbstractFragmentsBuilder(String[] preTags, String[] postTags) {
super(preTags, postTags); super(preTags, postTags);
} }
public AbstractFragmentsBuilder(String[] preTags, String[] postTags, BoundaryScanner bs) { public AbstractFragmentsBuilder(String[] preTags, String[] postTags, BoundaryScanner bs) {
super( preTags, postTags, bs ); super(preTags, postTags, bs);
} }
public void setDiscreteMultiValueHighlighting(boolean discreteMultiValueHighlighting) { public void setDiscreteMultiValueHighlighting(boolean discreteMultiValueHighlighting) {
@ -62,7 +62,6 @@ public abstract class AbstractFragmentsBuilder extends BaseFragmentsBuilder {
throw new IllegalArgumentException("maxNumFragments(" + maxNumFragments + ") must be positive number."); throw new IllegalArgumentException("maxNumFragments(" + maxNumFragments + ") must be positive number.");
} }
List<String> fragments = new ArrayList<String>(maxNumFragments);
List<FieldFragList.WeightedFragInfo> fragInfos = fieldFragList.getFragInfos(); List<FieldFragList.WeightedFragInfo> fragInfos = fieldFragList.getFragInfos();
Field[] values = getFields(reader, docId, fieldName); Field[] values = getFields(reader, docId, fieldName);
if (values.length == 0) { if (values.length == 0) {
@ -75,9 +74,12 @@ public abstract class AbstractFragmentsBuilder extends BaseFragmentsBuilder {
fragInfos = getWeightedFragInfoList(fragInfos); fragInfos = getWeightedFragInfoList(fragInfos);
int limitFragments = maxNumFragments < fragInfos.size() ? maxNumFragments : fragInfos.size();
List<String> fragments = new ArrayList<String>(limitFragments);
StringBuilder buffer = new StringBuilder(); StringBuilder buffer = new StringBuilder();
int[] nextValueIndex = {0}; int[] nextValueIndex = {0};
for (int n = 0; n < maxNumFragments && n < fragInfos.size(); n++) { for (int n = 0; n < limitFragments; n++) {
FieldFragList.WeightedFragInfo fragInfo = fragInfos.get(n); FieldFragList.WeightedFragInfo fragInfo = fragInfos.get(n);
fragments.add(makeFragment(buffer, nextValueIndex, values, fragInfo, preTags, postTags, encoder)); fragments.add(makeFragment(buffer, nextValueIndex, values, fragInfo, preTags, postTags, encoder));
} }

View File

@ -304,9 +304,10 @@ public class HighlightPhase extends AbstractComponent implements FetchSubPhase {
String[] fragments; String[] fragments;
// a HACK to make highlighter do highlighting, even though its using the single frag list builder // a HACK to make highlighter do highlighting, even though its using the single frag list builder
int numberOfFragments = field.numberOfFragments() == 0 ? 1 : field.numberOfFragments(); int numberOfFragments = field.numberOfFragments() == 0 ? Integer.MAX_VALUE : field.numberOfFragments();
int fragmentCharSize = field.numberOfFragments() == 0 ? Integer.MAX_VALUE : field.fragmentCharSize();
// we highlight against the low level reader and docId, because if we load source, we want to reuse it if possible // we highlight against the low level reader and docId, because if we load source, we want to reuse it if possible
fragments = cache.fvh.getBestFragments(fieldQuery, hitContext.reader(), hitContext.docId(), mapper.names().indexName(), field.fragmentCharSize(), numberOfFragments, fragments = cache.fvh.getBestFragments(fieldQuery, hitContext.reader(), hitContext.docId(), mapper.names().indexName(), fragmentCharSize, numberOfFragments,
entry.fragListBuilder, entry.fragmentsBuilder, field.preTags(), field.postTags(), encoder); entry.fragListBuilder, entry.fragmentsBuilder, field.preTags(), field.postTags(), encoder);
if (fragments != null && fragments.length > 0) { if (fragments != null && fragments.length > 0) {

View File

@ -26,6 +26,7 @@ import org.elasticsearch.client.Client;
import org.elasticsearch.common.settings.ImmutableSettings; import org.elasticsearch.common.settings.ImmutableSettings;
import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory; import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.indices.IndexMissingException; import org.elasticsearch.indices.IndexMissingException;
import org.elasticsearch.search.SearchHit; import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder; import org.elasticsearch.search.builder.SearchSourceBuilder;
@ -887,4 +888,35 @@ public class HighlighterSearchTests extends AbstractNodesTests {
assertThat(hit.highlightFields().get("title").fragments()[0].string(), equalTo("This is a <em>test</em> for the <em>workaround</em> for the fast vector highlighting SOLR-3724")); assertThat(hit.highlightFields().get("title").fragments()[0].string(), equalTo("This is a <em>test</em> for the <em>workaround</em> for the fast vector highlighting SOLR-3724"));
} }
} }
@Test
public void testFSHHighlightAllMvFragments() throws Exception {
try {
client.admin().indices().prepareDelete("test").execute().actionGet();
} catch (Exception e) {
// ignore
}
client.admin().indices().prepareCreate("test").setSettings(ImmutableSettings.settingsBuilder()
.put("number_of_shards", 1).put("number_of_replicas", 0))
.addMapping("type1", jsonBuilder().startObject().startObject("type1").startObject("properties")
.startObject("tags").field("type", "string").field("term_vector", "with_positions_offsets").endObject()
.endObject().endObject().endObject())
.execute().actionGet();
client.prepareIndex("test", "type1", "1")
.setSource(jsonBuilder().startObject().field("tags",
"this is a really long tag i would like to highlight",
"here is another one that is very long and has the tag token near the end").endObject())
.setRefresh(true).execute().actionGet();
SearchResponse response = client.prepareSearch("test")
.setQuery(QueryBuilders.matchQuery("tags", "tag"))
.addHighlightedField("tags", -1, 0)
.execute().actionGet();
assertThat(2, equalTo(response.hits().hits()[0].highlightFields().get("tags").fragments().length));
assertThat("this is a really long <em>tag</em> i would like to highlight", equalTo(response.hits().hits()[0].highlightFields().get("tags").fragments()[0].string()));
assertThat("here is another one that is very long and has the <em>tag</em> token near the end", equalTo(response.hits().hits()[0].highlightFields().get("tags").fragments()[1].string()));
}
} }