|
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