Skip to content

Commit 6cfd938

Browse files
committed
Fixed unable to highlight on all multi-valued field values.
Closes elastic#2384
1 parent f17ad82 commit 6cfd938

File tree

3 files changed

+43
-8
lines changed

3 files changed

+43
-8
lines changed

src/main/java/org/apache/lucene/search/vectorhighlight/AbstractFragmentsBuilder.java

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,20 +35,20 @@ public abstract class AbstractFragmentsBuilder extends BaseFragmentsBuilder {
3535

3636
private boolean discreteMultiValueHighlighting = true;
3737

38-
protected AbstractFragmentsBuilder(){
38+
protected AbstractFragmentsBuilder() {
3939
super();
4040
}
4141

42-
protected AbstractFragmentsBuilder(BoundaryScanner boundaryScanner){
42+
protected AbstractFragmentsBuilder(BoundaryScanner boundaryScanner) {
4343
super(boundaryScanner);
4444
}
4545

46-
protected AbstractFragmentsBuilder( String[] preTags, String[] postTags ){
46+
protected AbstractFragmentsBuilder(String[] preTags, String[] postTags) {
4747
super(preTags, postTags);
4848
}
4949

5050
public AbstractFragmentsBuilder(String[] preTags, String[] postTags, BoundaryScanner bs) {
51-
super( preTags, postTags, bs );
51+
super(preTags, postTags, bs);
5252
}
5353

5454
public void setDiscreteMultiValueHighlighting(boolean discreteMultiValueHighlighting) {
@@ -62,7 +62,6 @@ public String[] createFragments(IndexReader reader, int docId,
6262
throw new IllegalArgumentException("maxNumFragments(" + maxNumFragments + ") must be positive number.");
6363
}
6464

65-
List<String> fragments = new ArrayList<String>(maxNumFragments);
6665
List<FieldFragList.WeightedFragInfo> fragInfos = fieldFragList.getFragInfos();
6766
Field[] values = getFields(reader, docId, fieldName);
6867
if (values.length == 0) {
@@ -75,9 +74,12 @@ public String[] createFragments(IndexReader reader, int docId,
7574

7675
fragInfos = getWeightedFragInfoList(fragInfos);
7776

77+
int limitFragments = maxNumFragments < fragInfos.size() ? maxNumFragments : fragInfos.size();
78+
List<String> fragments = new ArrayList<String>(limitFragments);
79+
7880
StringBuilder buffer = new StringBuilder();
7981
int[] nextValueIndex = {0};
80-
for (int n = 0; n < maxNumFragments && n < fragInfos.size(); n++) {
82+
for (int n = 0; n < limitFragments; n++) {
8183
FieldFragList.WeightedFragInfo fragInfo = fragInfos.get(n);
8284
fragments.add(makeFragment(buffer, nextValueIndex, values, fragInfo, preTags, postTags, encoder));
8385
}

src/main/java/org/elasticsearch/search/highlight/HighlightPhase.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -304,9 +304,10 @@ public int compare(TextFragment o1, TextFragment o2) {
304304
String[] fragments;
305305

306306
// a HACK to make highlighter do highlighting, even though its using the single frag list builder
307-
int numberOfFragments = field.numberOfFragments() == 0 ? 1 : field.numberOfFragments();
307+
int numberOfFragments = field.numberOfFragments() == 0 ? Integer.MAX_VALUE : field.numberOfFragments();
308+
int fragmentCharSize = field.numberOfFragments() == 0 ? Integer.MAX_VALUE : field.fragmentCharSize();
308309
// we highlight against the low level reader and docId, because if we load source, we want to reuse it if possible
309-
fragments = cache.fvh.getBestFragments(fieldQuery, hitContext.reader(), hitContext.docId(), mapper.names().indexName(), field.fragmentCharSize(), numberOfFragments,
310+
fragments = cache.fvh.getBestFragments(fieldQuery, hitContext.reader(), hitContext.docId(), mapper.names().indexName(), fragmentCharSize, numberOfFragments,
310311
entry.fragListBuilder, entry.fragmentsBuilder, field.preTags(), field.postTags(), encoder);
311312

312313
if (fragments != null && fragments.length > 0) {

src/test/java/org/elasticsearch/test/integration/search/highlight/HighlighterSearchTests.java

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import org.elasticsearch.common.settings.ImmutableSettings;
2727
import org.elasticsearch.common.xcontent.XContentBuilder;
2828
import org.elasticsearch.common.xcontent.XContentFactory;
29+
import org.elasticsearch.index.query.QueryBuilders;
2930
import org.elasticsearch.indices.IndexMissingException;
3031
import org.elasticsearch.search.SearchHit;
3132
import org.elasticsearch.search.builder.SearchSourceBuilder;
@@ -887,4 +888,35 @@ public void testDisableFastVectorHighlighter() throws Exception {
887888
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"));
888889
}
889890
}
891+
892+
@Test
893+
public void testFSHHighlightAllMvFragments() throws Exception {
894+
try {
895+
client.admin().indices().prepareDelete("test").execute().actionGet();
896+
} catch (Exception e) {
897+
// ignore
898+
}
899+
900+
client.admin().indices().prepareCreate("test").setSettings(ImmutableSettings.settingsBuilder()
901+
.put("number_of_shards", 1).put("number_of_replicas", 0))
902+
.addMapping("type1", jsonBuilder().startObject().startObject("type1").startObject("properties")
903+
.startObject("tags").field("type", "string").field("term_vector", "with_positions_offsets").endObject()
904+
.endObject().endObject().endObject())
905+
.execute().actionGet();
906+
907+
client.prepareIndex("test", "type1", "1")
908+
.setSource(jsonBuilder().startObject().field("tags",
909+
"this is a really long tag i would like to highlight",
910+
"here is another one that is very long and has the tag token near the end").endObject())
911+
.setRefresh(true).execute().actionGet();
912+
913+
SearchResponse response = client.prepareSearch("test")
914+
.setQuery(QueryBuilders.matchQuery("tags", "tag"))
915+
.addHighlightedField("tags", -1, 0)
916+
.execute().actionGet();
917+
918+
assertThat(2, equalTo(response.hits().hits()[0].highlightFields().get("tags").fragments().length));
919+
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()));
920+
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()));
921+
}
890922
}

0 commit comments

Comments
 (0)