@Override
 public Query rewrite(IndexReader reader) throws IOException {
   Query rewritten = super.rewrite(reader);
   if (rewritten != this) {
     return rewritten;
   }
   if (termArrays.isEmpty()) {
     return new MatchNoDocsQuery();
   }
   MultiPhraseQuery.Builder query = new MultiPhraseQuery.Builder();
   query.setSlop(slop);
   int sizeMinus1 = termArrays.size() - 1;
   for (int i = 0; i < sizeMinus1; i++) {
     query.add(termArrays.get(i), positions.get(i));
   }
   Term[] suffixTerms = termArrays.get(sizeMinus1);
   int position = positions.get(sizeMinus1);
   ObjectHashSet<Term> terms = new ObjectHashSet<>();
   for (Term term : suffixTerms) {
     getPrefixTerms(terms, term, reader);
     if (terms.size() > maxExpansions) {
       break;
     }
   }
   if (terms.isEmpty()) {
     return Queries.newMatchNoDocsQuery();
   }
   query.add(terms.toArray(Term.class), position);
   return query.build();
 }
예제 #2
0
  // TODO: Move to QueryParserTestBase once standard flexible parser gets this capability
  public void testMultiWordSynonyms() throws Exception {
    QueryParser dumb = new QueryParser("field", new Analyzer1());
    dumb.setSplitOnWhitespace(false);

    // A multi-word synonym source will form a synonym query for the same-starting-position tokens
    BooleanQuery.Builder multiWordExpandedBqBuilder = new BooleanQuery.Builder();
    Query multiWordSynonymQuery =
        new SynonymQuery(new Term("field", "guinea"), new Term("field", "cavy"));
    multiWordExpandedBqBuilder.add(multiWordSynonymQuery, BooleanClause.Occur.SHOULD);
    multiWordExpandedBqBuilder.add(
        new TermQuery(new Term("field", "pig")), BooleanClause.Occur.SHOULD);
    Query multiWordExpandedBq = multiWordExpandedBqBuilder.build();
    assertEquals(multiWordExpandedBq, dumb.parse("guinea pig"));

    // With the phrase operator, a multi-word synonym source will form a multiphrase query.
    // When the number of expanded term(s) is different from that of the original term(s), this is
    // not good.
    MultiPhraseQuery.Builder multiWordExpandedMpqBuilder = new MultiPhraseQuery.Builder();
    multiWordExpandedMpqBuilder.add(
        new Term[] {new Term("field", "guinea"), new Term("field", "cavy")});
    multiWordExpandedMpqBuilder.add(new Term("field", "pig"));
    Query multiWordExpandedMPQ = multiWordExpandedMpqBuilder.build();
    assertEquals(multiWordExpandedMPQ, dumb.parse("\"guinea pig\""));

    // custom behavior, the synonyms are expanded, unless you use quote operator
    QueryParser smart = new SmartQueryParser();
    smart.setSplitOnWhitespace(false);
    assertEquals(multiWordExpandedBq, smart.parse("guinea pig"));

    PhraseQuery.Builder multiWordUnexpandedPqBuilder = new PhraseQuery.Builder();
    multiWordUnexpandedPqBuilder.add(new Term("field", "guinea"));
    multiWordUnexpandedPqBuilder.add(new Term("field", "pig"));
    Query multiWordUnexpandedPq = multiWordUnexpandedPqBuilder.build();
    assertEquals(multiWordUnexpandedPq, smart.parse("\"guinea pig\""));
  }
예제 #3
0
 /** forms multiphrase query */
 public void testSynonymsPhrase() throws Exception {
   MultiPhraseQuery.Builder expectedBuilder = new MultiPhraseQuery.Builder();
   expectedBuilder.add(new Term("field", "old"));
   expectedBuilder.add(new Term[] {new Term("field", "dogs"), new Term("field", "dog")});
   QueryBuilder builder = new QueryBuilder(new MockSynonymAnalyzer());
   assertEquals(expectedBuilder.build(), builder.createPhraseQuery("field", "old dogs"));
 }
예제 #4
0
 /** forms multiphrase query */
 public void testCJKSynonymsPhrase() throws Exception {
   MultiPhraseQuery.Builder expectedBuilder = new MultiPhraseQuery.Builder();
   expectedBuilder.add(new Term("field", "中"));
   expectedBuilder.add(new Term[] {new Term("field", "国"), new Term("field", "國")});
   QueryBuilder builder = new QueryBuilder(new MockCJKSynonymAnalyzer());
   assertEquals(expectedBuilder.build(), builder.createPhraseQuery("field", "中国"));
   expectedBuilder.setSlop(3);
   assertEquals(expectedBuilder.build(), builder.createPhraseQuery("field", "中国", 3));
 }
 /** forms multiphrase query */
 public void testCJKSynonymsPhrase() throws Exception {
   MultiPhraseQuery.Builder expectedQBuilder = new MultiPhraseQuery.Builder();
   expectedQBuilder.add(new Term("field", "中"));
   expectedQBuilder.add(new Term[] {new Term("field", "国"), new Term("field", "國")});
   QueryParser qp = new QueryParser("field", new MockCJKSynonymAnalyzer());
   qp.setDefaultOperator(Operator.AND);
   assertEquals(expectedQBuilder.build(), qp.parse("\"中国\""));
   Query expected = new BoostQuery(expectedQBuilder.build(), 2f);
   assertEquals(expected, qp.parse("\"中国\"^2"));
   expectedQBuilder.setSlop(3);
   expected = new BoostQuery(expectedQBuilder.build(), 2f);
   assertEquals(expected, qp.parse("\"中国\"~3^2"));
 }
예제 #6
0
 /** forms multiphrase query */
 public void testSynonymsPhrase() throws Exception {
   MultiPhraseQuery.Builder expectedQBuilder = new MultiPhraseQuery.Builder();
   expectedQBuilder.add(new Term(FIELD, "old"));
   expectedQBuilder.add(new Term[] {new Term(FIELD, "dogs"), new Term(FIELD, "dog")});
   QueryParser qp = new QueryParser(FIELD, new MockSynonymAnalyzer());
   assertEquals(expectedQBuilder.build(), qp.parse("\"old dogs\""));
   qp.setDefaultOperator(Operator.AND);
   assertEquals(expectedQBuilder.build(), qp.parse("\"old dogs\""));
   BoostQuery expected = new BoostQuery(expectedQBuilder.build(), 2f);
   assertEquals(expected, qp.parse("\"old dogs\"^2"));
   expectedQBuilder.setSlop(3);
   expected = new BoostQuery(expectedQBuilder.build(), 2f);
   assertEquals(expected, qp.parse("\"old dogs\"~3^2"));
 }