|
8 | 8 |
|
9 | 9 | package org.elasticsearch.index.query; |
10 | 10 |
|
11 | | -import org.apache.lucene.index.Term; |
12 | 11 | import org.apache.lucene.queries.intervals.FilteredIntervalsSource; |
13 | 12 | import org.apache.lucene.queries.intervals.IntervalIterator; |
14 | 13 | import org.apache.lucene.queries.intervals.Intervals; |
15 | 14 | import org.apache.lucene.queries.intervals.IntervalsSource; |
16 | | -import org.apache.lucene.search.FuzzyQuery; |
17 | 15 | import org.apache.lucene.util.BytesRef; |
18 | 16 | import org.elasticsearch.Version; |
19 | 17 | import org.elasticsearch.common.ParseField; |
@@ -128,23 +126,36 @@ public Match(StreamInput in) throws IOException { |
128 | 126 | } |
129 | 127 | } |
130 | 128 |
|
| 129 | + private IntervalsSource intervals(MappedFieldType fieldType, String text, int maxGaps, boolean ordered, NamedAnalyzer analyzer, |
| 130 | + SearchExecutionContext context) throws IOException { |
| 131 | + IntervalBuilder builder = new IntervalBuilder(fieldType.name(), analyzer) { |
| 132 | + @Override |
| 133 | + protected IntervalsSource termIntervals(BytesRef term) { |
| 134 | + return fieldType.termIntervals(term, context); |
| 135 | + } |
| 136 | + }; |
| 137 | + return builder.analyzeText(text, maxGaps, ordered); |
| 138 | + } |
| 139 | + |
131 | 140 | @Override |
132 | 141 | public IntervalsSource getSource(SearchExecutionContext context, MappedFieldType fieldType) throws IOException { |
133 | 142 | NamedAnalyzer analyzer = null; |
134 | 143 | if (this.analyzer != null) { |
135 | 144 | analyzer = context.getIndexAnalyzers().get(this.analyzer); |
136 | 145 | } |
137 | | - IntervalsSource source; |
138 | 146 | if (useField != null) { |
139 | 147 | fieldType = context.getFieldType(useField); |
140 | 148 | assert fieldType != null; |
141 | | - source = Intervals.fixField(useField, fieldType.intervals(query, maxGaps, ordered, analyzer, false)); |
142 | 149 | } |
143 | | - else { |
144 | | - source = fieldType.intervals(query, maxGaps, ordered, analyzer, false); |
| 150 | + if (analyzer == null) { |
| 151 | + analyzer = fieldType.getTextSearchInfo().getSearchAnalyzer(); |
| 152 | + } |
| 153 | + IntervalsSource source = intervals(fieldType, query, maxGaps, ordered, analyzer, context); |
| 154 | + if (useField != null) { |
| 155 | + source = Intervals.fixField(useField, source); |
145 | 156 | } |
146 | 157 | if (filter != null) { |
147 | | - return filter.filter(source, context, fieldType); |
| 158 | + source = filter.filter(source, context, fieldType); |
148 | 159 | } |
149 | 160 | return source; |
150 | 161 | } |
@@ -517,14 +528,17 @@ public IntervalsSource getSource(SearchExecutionContext context, MappedFieldType |
517 | 528 | if (this.analyzer != null) { |
518 | 529 | analyzer = context.getIndexAnalyzers().get(this.analyzer); |
519 | 530 | } |
520 | | - IntervalsSource source; |
521 | 531 | if (useField != null) { |
522 | 532 | fieldType = context.getFieldType(useField); |
523 | 533 | assert fieldType != null; |
524 | | - source = Intervals.fixField(useField, fieldType.intervals(prefix, 0, false, analyzer, true)); |
525 | 534 | } |
526 | | - else { |
527 | | - source = fieldType.intervals(prefix, 0, false, analyzer, true); |
| 535 | + if (analyzer == null) { |
| 536 | + analyzer = fieldType.getTextSearchInfo().getSearchAnalyzer(); |
| 537 | + } |
| 538 | + final BytesRef prefixTerm = analyzer.normalize(fieldType.name(), prefix); |
| 539 | + IntervalsSource source = fieldType.prefixIntervals(prefixTerm, context); |
| 540 | + if (useField != null) { |
| 541 | + source = Intervals.fixField(useField, source); |
528 | 542 | } |
529 | 543 | return source; |
530 | 544 | } |
@@ -628,33 +642,23 @@ public Wildcard(StreamInput in) throws IOException { |
628 | 642 |
|
629 | 643 | @Override |
630 | 644 | public IntervalsSource getSource(SearchExecutionContext context, MappedFieldType fieldType) { |
631 | | - NamedAnalyzer analyzer = fieldType.getTextSearchInfo().getSearchAnalyzer(); |
| 645 | + NamedAnalyzer analyzer = null; |
632 | 646 | if (this.analyzer != null) { |
633 | 647 | analyzer = context.getIndexAnalyzers().get(this.analyzer); |
634 | 648 | } |
635 | | - IntervalsSource source; |
636 | 649 | if (useField != null) { |
637 | 650 | fieldType = context.getFieldType(useField); |
638 | 651 | assert fieldType != null; |
639 | | - checkPositions(fieldType); |
640 | | - if (this.analyzer == null) { |
641 | | - analyzer = fieldType.getTextSearchInfo().getSearchAnalyzer(); |
642 | | - } |
643 | | - BytesRef normalizedTerm = analyzer.normalize(useField, pattern); |
644 | | - source = Intervals.fixField(useField, Intervals.wildcard(normalizedTerm)); |
645 | 652 | } |
646 | | - else { |
647 | | - checkPositions(fieldType); |
648 | | - BytesRef normalizedTerm = analyzer.normalize(fieldType.name(), pattern); |
649 | | - source = Intervals.wildcard(normalizedTerm); |
| 653 | + if (analyzer == null) { |
| 654 | + analyzer = fieldType.getTextSearchInfo().getSearchAnalyzer(); |
650 | 655 | } |
651 | | - return source; |
652 | | - } |
653 | | - |
654 | | - private void checkPositions(MappedFieldType type) { |
655 | | - if (type.getTextSearchInfo().hasPositions() == false) { |
656 | | - throw new IllegalArgumentException("Cannot create intervals over field [" + type.name() + "] with no positions indexed"); |
| 656 | + BytesRef normalizedPattern = analyzer.normalize(fieldType.name(), pattern); |
| 657 | + IntervalsSource source = fieldType.wildcardIntervals(normalizedPattern, context); |
| 658 | + if (useField != null) { |
| 659 | + source = Intervals.fixField(useField, source); |
657 | 660 | } |
| 661 | + return source; |
658 | 662 | } |
659 | 663 |
|
660 | 664 | @Override |
@@ -765,36 +769,27 @@ public Fuzzy(StreamInput in) throws IOException { |
765 | 769 |
|
766 | 770 | @Override |
767 | 771 | public IntervalsSource getSource(SearchExecutionContext context, MappedFieldType fieldType) { |
768 | | - NamedAnalyzer analyzer = fieldType.getTextSearchInfo().getSearchAnalyzer(); |
| 772 | + NamedAnalyzer analyzer = null; |
769 | 773 | if (this.analyzer != null) { |
770 | 774 | analyzer = context.getIndexAnalyzers().get(this.analyzer); |
771 | 775 | } |
772 | | - IntervalsSource source; |
773 | 776 | if (useField != null) { |
774 | 777 | fieldType = context.getFieldType(useField); |
775 | 778 | assert fieldType != null; |
776 | | - checkPositions(fieldType); |
777 | | - if (this.analyzer == null) { |
778 | | - analyzer = fieldType.getTextSearchInfo().getSearchAnalyzer(); |
779 | | - } |
780 | 779 | } |
781 | | - checkPositions(fieldType); |
782 | | - BytesRef normalizedTerm = analyzer.normalize(fieldType.name(), term); |
783 | | - FuzzyQuery fq = new FuzzyQuery(new Term(fieldType.name(), normalizedTerm), |
784 | | - fuzziness.asDistance(term), prefixLength, 128, transpositions); |
785 | | - source = Intervals.multiterm(fq.getAutomata(), term); |
| 780 | + if (analyzer == null) { |
| 781 | + analyzer = fieldType.getTextSearchInfo().getSearchAnalyzer(); |
| 782 | + } |
| 783 | + // Fuzzy queries only work with unicode content so it's legal to call utf8ToString here. |
| 784 | + String normalizedTerm = analyzer.normalize(fieldType.name(), term).utf8ToString(); |
| 785 | + IntervalsSource source = fieldType.fuzzyIntervals(normalizedTerm, fuzziness.asDistance(term), |
| 786 | + prefixLength, transpositions, context); |
786 | 787 | if (useField != null) { |
787 | 788 | source = Intervals.fixField(useField, source); |
788 | 789 | } |
789 | 790 | return source; |
790 | 791 | } |
791 | 792 |
|
792 | | - private void checkPositions(MappedFieldType type) { |
793 | | - if (type.getTextSearchInfo().hasPositions() == false) { |
794 | | - throw new IllegalArgumentException("Cannot create intervals over field [" + type.name() + "] with no positions indexed"); |
795 | | - } |
796 | | - } |
797 | | - |
798 | 793 | @Override |
799 | 794 | public void extractFields(Set<String> fields) { |
800 | 795 | if (useField != null) { |
|
0 commit comments