Refine search
protected Query eq(String field, String[] terms, boolean ignoreCase) { if (terms.length > 1) { PhraseQuery pq = new PhraseQuery(); for (String s : terms) { pq.add(new Term(field, s)); } return pq; } return new TermQuery(new Term(field, terms[0])); }
@Override public Query rewrite(IndexReader reader) throws IOException { final Term[] terms = phraseQuery.getTerms(); final int[] positions = phraseQuery.getPositions(); boolean isOptimizable = phraseQuery.getSlop() == 0 && n >= 2 // non-overlap n-gram cannot be optimized && terms.length >= 3; // short ones can't be optimized if (isOptimizable) { for (int i = 1; i < positions.length; ++i) { if (positions[i] != positions[i-1] + 1) { isOptimizable = false; break; } } } if (isOptimizable == false) { return phraseQuery.rewrite(reader); } PhraseQuery.Builder builder = new PhraseQuery.Builder(); for (int i = 0; i < terms.length; ++i) { if (i % n == 0 || i == terms.length - 1) { builder.add(terms[i], i); } } return builder.build(); }
return null; else if (v.size() == 1) return new TermQuery(new Term(field, (String) v.elementAt(0))); else { PhraseQuery q = new PhraseQuery(); q.setSlop(phraseSlop); for (int i=0; i<v.size(); i++) { q.add(new Term(field, (String) v.elementAt(i)));
private void checkOverlap( Collection<Query> expandQueries, Term[] src, Term[] dest, int slop, float boost ){ // beginning from 1 (not 0) is safe because that the PhraseQuery has multiple terms // is guaranteed in flatten() method (if PhraseQuery has only one term, flatten() // converts PhraseQuery to TermQuery) for( int i = 1; i < src.length; i++ ){ boolean overlap = true; for( int j = i; j < src.length; j++ ){ if( ( j - i ) < dest.length && !src[j].text().equals( dest[j-i].text() ) ){ overlap = false; break; } } if( overlap && src.length - i < dest.length ){ PhraseQuery pq = new PhraseQuery(); for( Term srcTerm : src ) pq.add( srcTerm ); for( int k = src.length - i; k < dest.length; k++ ){ pq.add( new Term( src[0].field(), dest[k].text() ) ); } pq.setSlop( slop ); pq.setBoost( boost ); if(!expandQueries.contains( pq ) ) expandQueries.add( pq ); } } }
/** * Expand a {@link PhraseQuery} to multiple fields that share the same analyzer. * Returns a {@link DisjunctionMaxQuery} with a disjunction for each expanded field. */ static Query blendPhrase(PhraseQuery query, float tiebreaker, FieldAndFieldType... fields) { List<Query> disjunctions = new ArrayList<>(); for (FieldAndFieldType field : fields) { int[] positions = query.getPositions(); Term[] terms = query.getTerms(); PhraseQuery.Builder builder = new PhraseQuery.Builder(); for (int i = 0; i < terms.length; i++) { builder.add(new Term(field.fieldType.name(), terms[i].bytes()), positions[i]); } Query q = builder.build(); if (field.boost != AbstractQueryBuilder.DEFAULT_BOOST) { q = new BoostQuery(q, field.boost); } disjunctions.add(q); } return new DisjunctionMaxQuery(disjunctions, tiebreaker); }
else if (list.size() == 1) { nextToken = (org.apache.lucene.analysis.Token) list.get(0); return newTermQuery(new Term(field, nextToken.term())); } else { if (severalTokensAtSamePosition) { nextToken = (org.apache.lucene.analysis.Token) list.get(i); Query currentQuery = newTermQuery( new Term(field, nextToken.term())); q.add(currentQuery, BooleanClause.Occur.SHOULD); multiTerms.add(new Term(field, nextToken.term())); pq.setSlop(phraseSlop); int position = -1; for (int i = 0; i < list.size(); i++) { if (enablePositionIncrements) { position += nextToken.getPositionIncrement(); pq.add(new Term(field, nextToken.term()),position); } else { pq.add(new Term(field, nextToken.term()));
private void checkOverlap( Collection<Query> expandQueries, PhraseQuery a, PhraseQuery b ){ if( a.getSlop() != b.getSlop() ) return; Term[] ats = a.getTerms(); Term[] bts = b.getTerms(); if( fieldMatch && !ats[0].field().equals( bts[0].field() ) ) return; checkOverlap( expandQueries, ats, bts, a.getSlop(), a.getBoost() ); checkOverlap( expandQueries, bts, ats, b.getSlop(), b.getBoost() ); }
@Override public Query visit(PhraseQuery phraseQuery) { PhraseQuery newQuery = new PhraseQuery(); for(Term term: phraseQuery.getTerms()) { Field field = Field.getByName( term.field() ); if( field != Field.CONTENTS ) return phraseQuery; Term newTerm = Field.CONTENTS.createTerm( term.text().toLowerCase(Locale.ENGLISH) ); newQuery.add( newTerm ); } newQuery.setSlop(phraseQuery.getSlop()); newQuery.setBoost( phraseQuery.getBoost() ); return newQuery; } }
private QueryNode internalParse(org.apache.lucene.search.Query luceneQuery, final String originalStr) throws ParseException { QueryNode node; if (luceneQuery instanceof org.apache.lucene.search.TermQuery) { Term t = ((org.apache.lucene.search.TermQuery) luceneQuery).getTerm(); String field = t.field(); String text = t.text(); node = new TermQuery(field, text); } else if (luceneQuery instanceof org.apache.lucene.search.PrefixQuery) { Term t = ((org.apache.lucene.search.PrefixQuery) luceneQuery).getPrefix(); String field = t.field(); String text = t.text(); node = new PrefixTermQuery(field, text); } else if (luceneQuery instanceof org.apache.lucene.search.BooleanQuery) { List<BooleanClause> clauses = ((org.apache.lucene.search.BooleanQuery) luceneQuery).clauses(); if (clauses.isEmpty()) { throw new ParseException("error parsing: " + originalStr); } node = internalParseBooleanQuery(clauses, originalStr); } else if (luceneQuery instanceof org.apache.lucene.search.PhraseQuery) { org.apache.lucene.search.PhraseQuery phraseQuery = (org.apache.lucene.search.PhraseQuery) luceneQuery; int[] positions = phraseQuery.getPositions(); node = internalParsePhraseQuery(phraseQuery.getTerms(), positions, originalStr); } else { throw new ParseException("unimplemented"); } node.setBoost(luceneQuery.getBoost()); return node; }
@Override public BooleanQuery visit(BooleanQuery boolQuery) PhraseQuery phraseQuery = new PhraseQuery(); Field field = Field.getByName( tq.getTerm().field() ); if( field != Field.CONTENTS ) continue; phraseQuery.add(tq.getTerm()); phraseQuery.setSlop(DEFAULT_SLOP); bq.setBoost(boolQuery.getBoost()); phraseQuery.setBoost(boolQuery.getBoost()); boolQuery.setBoost( phraseQuery.getBoost()*0.5f );
protected void flattenQuery(PhraseQuery query, float pathBoost, Object sourceOverride, IndexReader reader, Callback callback) { Term[] terms = query.getTerms(); if (terms.length == 0) { return; } if (phraseAsTerms) { for (Term term : terms) { callback.flattened(term.bytes(), pathBoost, sourceOverride); } } else { callback.startPhrase(terms.length, pathBoost); for (Term term : terms) { callback.startPhrasePosition(1); callback.flattened(term.bytes(), 0, sourceOverride); callback.endPhrasePosition(); } callback.endPhrase(terms[0].field(), query.getSlop(), pathBoost); } }
private String getKey( Query query ){ if( !fieldMatch ) return null; if( query instanceof TermQuery ) return ((TermQuery)query).getTerm().field(); else if ( query instanceof PhraseQuery ){ PhraseQuery pq = (PhraseQuery)query; Term[] terms = pq.getTerms(); return terms[0].field(); } else throw new RuntimeException( "query \"" + query.toString() + "\" must be flatten first." ); }
PhraseQuery replaced = new PhraseQuery(); replaced.setBoost(original.getBoost()); replaced.setSlop(original.getSlop()); Term[] terms = original.getTerms(); int[] positions = original.getPositions(); for (int i = 0; i < terms.length; i++) { replaced.add(visitor.replaceTerm(terms[i]), positions[i]);
private void checkOverlap( Collection<Query> expandQueries, PhraseQuery a, float aBoost, PhraseQuery b, float bBoost ){ if( a.getSlop() != b.getSlop() ) return; Term[] ats = a.getTerms(); Term[] bts = b.getTerms(); if( fieldMatch && !ats[0].field().equals( bts[0].field() ) ) return; checkOverlap( expandQueries, ats, bts, a.getSlop(), aBoost); checkOverlap( expandQueries, bts, ats, b.getSlop(), bBoost ); }
void add( Query query, IndexReader reader ) { float boost = 1f; while (query instanceof BoostQuery) { BoostQuery bq = (BoostQuery) query; query = bq.getQuery(); boost = bq.getBoost(); } if( query instanceof TermQuery ){ addTerm( ((TermQuery)query).getTerm(), boost ); } else if( query instanceof PhraseQuery ){ PhraseQuery pq = (PhraseQuery)query; Term[] terms = pq.getTerms(); Map<String, QueryPhraseMap> map = subMap; QueryPhraseMap qpm = null; for( Term term : terms ){ qpm = getOrNewMap( map, term.text() ); map = qpm.subMap; } qpm.markTerminal( pq.getSlop(), boost ); } else throw new RuntimeException( "query \"" + query.toString() + "\" must be flatten first." ); }
/** * Rebuild a phrase query with a slop value */ private PhraseQuery addSlopToPhrase(PhraseQuery query, int slop) { PhraseQuery.Builder builder = new PhraseQuery.Builder(); builder.setSlop(slop); final Term[] terms = query.getTerms(); final int[] positions = query.getPositions(); for (int i = 0; i < terms.length; ++i) { builder.add(terms[i], positions[i]); } return builder.build(); }
@Override public Query rewrite(IndexReader reader) throws IOException { if (terms.isEmpty()) { Query rewritten = new MatchNoDocsQuery(); rewritten.setBoost(getBoost()); return rewritten; } else if (terms.size() == 1) { TermQuery tq = new TermQuery(terms.get(0)); tq.setBoost(getBoost()); return tq; } else if (positions.get(0).intValue() != 0) { final int[] oldPositions = getPositions(); int[] newPositions = new int[oldPositions.length]; for (int i = 0; i < oldPositions.length; ++i) { newPositions[i] = oldPositions[i] - oldPositions[0]; } PhraseQuery rewritten = new PhraseQuery(slop, getTerms(), newPositions); rewritten.setBoost(getBoost()); return rewritten; } else { return super.rewrite(reader); } }
/** Prints a user-readable version of this query. */ public String toString(String f) { StringBuffer buffer = new StringBuffer(); if (!field.equals(f)) { buffer.append(field); buffer.append(":"); } buffer.append("\""); for (int i = 0; i < terms.size(); i++) { buffer.append(((Term)terms.elementAt(i)).text()); if (i != terms.size()-1) buffer.append(" "); } buffer.append("\""); if (slop != 0) { buffer.append("~"); buffer.append(slop); } if (getBoost() != 1.0f) { buffer.append("^"); buffer.append(Float.toString(getBoost())); } return buffer.toString(); }