List of usage examples for org.apache.lucene.search DisjunctionMaxQuery DisjunctionMaxQuery
public DisjunctionMaxQuery(Collection<Query> disjuncts, float tieBreakerMultiplier)
From source file:com.qwazr.search.bench.test.MultiField.PayloadDismaxQuery.java
License:Apache License
@Override public Query getQuery(QueryContext queryContext) throws IOException, ParseException, QueryNodeException, ReflectiveOperationException { final List<Query> queries = new ArrayList<>(); final Analyzer analyzer = queryContext.getQueryAnalyzer(); final BooleanClause.Occur occur = operator == null || operator == QueryParserOperator.AND ? BooleanClause.Occur.MUST/*w ww . j ava 2s. c o m*/ : BooleanClause.Occur.SHOULD; for (String field : fields) queries.add(new PayloadQueryBuilder(analyzer).createBooleanQuery(field, queryString, occur)); return new DisjunctionMaxQuery(queries, tieBreak); }
From source file:de.hybris.platform.solr.search.MultiMaxScoreQParser.java
License:Open Source License
@Override public Query parse() throws SyntaxError { final Query q = super.parse(); if (!(q instanceof BooleanQuery)) { return q; }/* w ww. ja v a2 s.co m*/ final BooleanQuery oldQuery = (BooleanQuery) q; final BooleanQuery.Builder newQuery = new BooleanQuery.Builder(); List<Query> disjuncts = null; for (final BooleanClause clause : oldQuery.clauses()) { if (clause.isProhibited() || clause.isRequired()) { newQuery.add(clause); } else { final Query subQuery = clause.getQuery(); if (!(subQuery instanceof BooleanQuery)) { if (disjuncts == null) { disjuncts = new ArrayList<>(); } disjuncts.add(clause.getQuery()); } else { final List<Query> subQueriesList = new ArrayList<>(); for (final BooleanClause subQueryClause : ((BooleanQuery) subQuery).clauses()) { subQueriesList.add(subQueryClause.getQuery()); } final DisjunctionMaxQuery subDmq = new DisjunctionMaxQuery(subQueriesList, tie); newQuery.add(subDmq, BooleanClause.Occur.SHOULD); } } } if (CollectionUtils.isNotEmpty(disjuncts)) { final DisjunctionMaxQuery disjunctionQuery = new DisjunctionMaxQuery(disjuncts, tie); newQuery.add(disjunctionQuery, BooleanClause.Occur.SHOULD); } return newQuery.build(); }
From source file:de.unihildesheim.iw.lucene.query.RelaxableCommonTermsQuery.java
License:Open Source License
/** * New instance using settings from the supplied {@link Builder} instance. * * @param builder {@link Builder} Instance builder * @throws IOException Thrown on low-level i/o-errors *///from w w w . jav a 2s. c o m @SuppressWarnings({ "ObjectAllocationInLoop", "ObjectEquality" }) RelaxableCommonTermsQuery(@NotNull final Builder builder) throws IOException { // get all query terms assert builder.queryStr != null; assert builder.analyzer != null; this.queryTerms = QueryUtils.tokenizeQueryString(builder.queryStr, builder.analyzer); // list of unique terms contained in the query (stopped, analyzed) final String[] uniqueQueryTerms = this.queryTerms.stream().distinct().toArray(String[]::new); final int uniqueTermsCount = uniqueQueryTerms.length; // heavily based on code from org.apache.lucene.queries.CommonTermsQuery assert builder.reader != null; final List<LeafReaderContext> leaves = builder.reader.leaves(); final int maxDoc = builder.reader.maxDoc(); TermsEnum termsEnum = null; final List<Query> subQueries = new ArrayList<>(10); assert builder.fields != null; for (final String field : builder.fields) { final TermContext[] tcArray = new TermContext[uniqueTermsCount]; final BooleanQuery lowFreq = new BooleanQuery(); final BooleanQuery highFreq = new BooleanQuery(); // collect term statistics for (int i = 0; i < uniqueTermsCount; i++) { final Term term = new Term(field, uniqueQueryTerms[i]); for (final LeafReaderContext context : leaves) { final TermContext termContext = tcArray[i]; final Fields fields = context.reader().fields(); final Terms terms = fields.terms(field); if (terms != null) { // only, if field exists termsEnum = terms.iterator(termsEnum); if (termsEnum != TermsEnum.EMPTY) { if (termsEnum.seekExact(term.bytes())) { if (termContext == null) { tcArray[i] = new TermContext(builder.reader.getContext(), termsEnum.termState(), context.ord, termsEnum.docFreq(), termsEnum.totalTermFreq()); } else { termContext.register(termsEnum.termState(), context.ord, termsEnum.docFreq(), termsEnum.totalTermFreq()); } } } } } // build query if (tcArray[i] == null) { lowFreq.add(new TermQuery(term), builder.lowFreqOccur); } else { if ((builder.maxTermFrequency >= 1f && (float) tcArray[i].docFreq() > builder.maxTermFrequency) || (tcArray[i].docFreq() > (int) Math .ceil((double) (builder.maxTermFrequency * (float) maxDoc)))) { highFreq.add(new TermQuery(term, tcArray[i]), builder.highFreqOccur); } else { lowFreq.add(new TermQuery(term, tcArray[i]), builder.lowFreqOccur); } } final int numLowFreqClauses = lowFreq.clauses().size(); final int numHighFreqClauses = highFreq.clauses().size(); if (builder.lowFreqOccur == Occur.SHOULD && numLowFreqClauses > 0) { lowFreq.setMinimumNumberShouldMatch(numLowFreqClauses); } if (builder.highFreqOccur == Occur.SHOULD && numHighFreqClauses > 0) { highFreq.setMinimumNumberShouldMatch(numHighFreqClauses); } } if (LOG.isDebugEnabled()) { LOG.debug("qLF={}", lowFreq); LOG.debug("qHF={}", highFreq); } if (lowFreq.clauses().isEmpty()) { subQueries.add(highFreq); } else if (highFreq.clauses().isEmpty()) { subQueries.add(lowFreq); } else { final BooleanQuery query = new BooleanQuery(true); // final query query.add(highFreq, Occur.SHOULD); query.add(lowFreq, Occur.MUST); subQueries.add(query); } } if (LOG.isDebugEnabled()) { LOG.debug("qList={}", subQueries); } this.query = subQueries.size() == 1 ? subQueries.get(0) : new DisjunctionMaxQuery(subQueries, 0.1f); if (LOG.isDebugEnabled()) { LOG.debug("RCTQ {} uQt={}", this.query, uniqueQueryTerms); } }
From source file:org.apache.solr.search.MaxScoreQParser.java
License:Apache License
/** * Parses the query exactly like the Lucene parser does, but * delegates all SHOULD clauses to DisjunctionMaxQuery with * meaning only the clause with the max score will contribute * to the overall score, unless the tie parameter is specified. * <br/>/*from www . j a v a 2 s .c om*/ * The max() is only calculated from the SHOULD clauses. * Any MUST clauses will be passed through as separate * BooleanClauses and thus always contribute to the score. * @return the resulting Query * @throws org.apache.solr.search.SyntaxError if parsing fails */ @Override public Query parse() throws SyntaxError { Query q = super.parse(); if (!(q instanceof BooleanQuery)) { return q; } BooleanQuery obq = (BooleanQuery) q; Collection<Query> should = new ArrayList<Query>(); Collection<BooleanClause> prohibOrReq = new ArrayList<BooleanClause>(); BooleanQuery newq = new BooleanQuery(); for (BooleanClause clause : obq.getClauses()) { if (clause.isProhibited() || clause.isRequired()) { prohibOrReq.add(clause); } else { BooleanQuery bq = new BooleanQuery(); bq.add(clause); should.add(bq); } } if (should.size() > 0) { DisjunctionMaxQuery dmq = new DisjunctionMaxQuery(should, tie); newq.add(dmq, BooleanClause.Occur.SHOULD); } for (BooleanClause c : prohibOrReq) { newq.add(c); } newq.setBoost(obq.getBoost()); return newq; }
From source file:org.codelibs.elasticsearch.index.query.DisMaxQueryBuilder.java
License:Apache License
@Override protected Query doToQuery(QueryShardContext context) throws IOException { // return null if there are no queries at all Collection<Query> luceneQueries = toQueries(queries, context); if (luceneQueries.isEmpty()) { return Queries.newMatchNoDocsQuery("no clauses for dismax query."); }/*from ww w .j a va 2s. co m*/ return new DisjunctionMaxQuery(luceneQueries, tieBreaker); }
From source file:org.codice.ddf.spatial.geocoding.query.GeoNamesQueryLuceneIndex.java
License:Open Source License
protected Query createQuery(final String queryString) throws ParseException { final StandardAnalyzer standardAnalyzer = new StandardAnalyzer(); final QueryParser nameQueryParser = new QueryParser(GeoNamesLuceneConstants.NAME_FIELD, standardAnalyzer); nameQueryParser.setEnablePositionIncrements(false); /* For the name, we construct a query searching for exactly the query string (the phrase query), a query searching for all the terms in the query string (the AND query), and a query searching for any of the terms in the query string (the OR query). We take the maximum of the scores generated by these three queries and use that as the score for the name. *//*from ww w. j av a2 s . c om*/ // Surround with quotes so Lucene looks for the words in the query as a phrase. // Phrase query gets the biggest boost - 3.2 was obtained after some experimentation. final Query phraseNameQuery = new BoostQuery(nameQueryParser.parse("\"" + queryString + "\""), 3.2f); // By default, QueryParser uses OR to separate terms. // We give OR queries the lowest boost because they're not as good as phrase matches or // AND matches - 1 (the default boost value) was obtained after some experimentation. final Query orNameQuery = nameQueryParser.parse(queryString); nameQueryParser.setDefaultOperator(QueryParser.AND_OPERATOR); // We give AND queries the second-biggest boost because they're better than OR matches but // not as good as phrase matches - 2 was obtained after some experimentation. final Query andNameQuery = new BoostQuery(nameQueryParser.parse(queryString), 2f); final List<Query> nameQueryList = Arrays.asList(phraseNameQuery, orNameQuery, andNameQuery); // This query will score each document by the maximum of the three sub-queries. final Query nameQuery = new DisjunctionMaxQuery(nameQueryList, 0); final QueryParser alternateNamesQueryParser = new QueryParser(GeoNamesLuceneConstants.ALTERNATE_NAMES_FIELD, standardAnalyzer); // For the alternate names, we perform an AND query and an OR query, both of which are // boosted less than the name query because the alternate names are generally not as // important. // The OR query gets a lower boost - 0.5 was obtained after some experimentation. final Query orAlternateNamesQuery = new BoostQuery(alternateNamesQueryParser.parse(queryString), 0.5f); alternateNamesQueryParser.setDefaultOperator(QueryParser.AND_OPERATOR); // The AND query gets a higher boost - 1 (the default boost value) was obtained after some // experimentation. final Query andAlternateNamesQuery = alternateNamesQueryParser.parse(queryString); final List<Query> alternateNamesQueryList = Arrays.asList(orAlternateNamesQuery, andAlternateNamesQuery); // This query will score each document by the maximum of the two sub-queries. final Query alternateNamesQuery = new DisjunctionMaxQuery(alternateNamesQueryList, 0); final List<Query> queryList = Arrays.asList(nameQuery, alternateNamesQuery); // This query will score each document by the sum of the two sub-queries, since both the // name and the alternate names are important. // The boost values ensure that how well the query matches the name has a bigger impact on // the final score than how well it matches the alternate names. final DisjunctionMaxQuery disjunctionMaxQuery = new DisjunctionMaxQuery(queryList, 1.0f); // This is the boost we calculated at index time, and it is applied in the CustomScoreQuery. final FunctionQuery boostQuery = new FunctionQuery( new FloatFieldSource(GeoNamesLuceneConstants.BOOST_FIELD)); return new CustomScoreQuery(disjunctionMaxQuery, boostQuery); }
From source file:org.elasticsearch.index.query.DisMaxQueryParser.java
License:Apache License
@Override public Query parse(QueryParseContext parseContext) throws IOException, QueryParsingException { XContentParser parser = parseContext.parser(); float boost = 1.0f; float tieBreaker = 0.0f; List<Query> queries = newArrayList(); boolean queriesFound = false; String queryName = null;/*from w w w. java2s . c o m*/ String currentFieldName = null; XContentParser.Token token; while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) { if (token == XContentParser.Token.FIELD_NAME) { currentFieldName = parser.currentName(); } else if (token == XContentParser.Token.START_OBJECT) { if ("queries".equals(currentFieldName)) { queriesFound = true; Query query = parseContext.parseInnerQuery(); if (query != null) { queries.add(query); } } else { throw new QueryParsingException(parseContext.index(), "[dis_max] query does not support [" + currentFieldName + "]"); } } else if (token == XContentParser.Token.START_ARRAY) { if ("queries".equals(currentFieldName)) { queriesFound = true; while (token != XContentParser.Token.END_ARRAY) { Query query = parseContext.parseInnerQuery(); if (query != null) { queries.add(query); } token = parser.nextToken(); } } else { throw new QueryParsingException(parseContext.index(), "[dis_max] query does not support [" + currentFieldName + "]"); } } else { if ("boost".equals(currentFieldName)) { boost = parser.floatValue(); } else if ("tie_breaker".equals(currentFieldName) || "tieBreaker".equals(currentFieldName)) { tieBreaker = parser.floatValue(); } else if ("_name".equals(currentFieldName)) { queryName = parser.text(); } else { throw new QueryParsingException(parseContext.index(), "[dis_max] query does not support [" + currentFieldName + "]"); } } } if (!queriesFound) { throw new QueryParsingException(parseContext.index(), "[dis_max] requires 'queries' field"); } if (queries.isEmpty()) { return null; } DisjunctionMaxQuery query = new DisjunctionMaxQuery(queries, tieBreaker); query.setBoost(boost); if (queryName != null) { parseContext.addNamedQuery(queryName, query); } return query; }
From source file:org.elasticsearch.index.query.json.DisMaxJsonQueryParser.java
License:Apache License
@Override public Query parse(JsonQueryParseContext parseContext) throws IOException, QueryParsingException { JsonParser jp = parseContext.jp();//from www . j av a 2s. c o m float boost = 1.0f; float tieBreaker = 0.0f; List<Query> queries = newArrayList(); String currentFieldName = null; JsonToken token; while ((token = jp.nextToken()) != JsonToken.END_OBJECT) { if (token == JsonToken.FIELD_NAME) { currentFieldName = jp.getCurrentName(); } else if (token == JsonToken.START_OBJECT) { if ("queries".equals(currentFieldName)) { queries.add(parseContext.parseInnerQuery()); } } else if (token == JsonToken.START_ARRAY) { if ("queries".equals(currentFieldName)) { while (token != JsonToken.END_ARRAY) { queries.add(parseContext.parseInnerQuery()); token = jp.nextToken(); } } } else { if ("boost".equals(currentFieldName)) { if (token == JsonToken.VALUE_STRING) { boost = Float.parseFloat(jp.getText()); } else { boost = jp.getFloatValue(); } } else if ("tie_breaker".equals(currentFieldName)) { if (token == JsonToken.VALUE_STRING) { tieBreaker = Float.parseFloat(jp.getText()); } else { tieBreaker = jp.getFloatValue(); } } } } DisjunctionMaxQuery query = new DisjunctionMaxQuery(queries, tieBreaker); query.setBoost(boost); return query; }
From source file:org.elasticsearch.index.query.xcontent.DisMaxQueryParser.java
License:Apache License
@Override public Query parse(QueryParseContext parseContext) throws IOException, QueryParsingException { XContentParser parser = parseContext.parser(); float boost = 1.0f; float tieBreaker = 0.0f; List<Query> queries = newArrayList(); String currentFieldName = null; XContentParser.Token token;/*w w w.j av a 2 s. c o m*/ while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) { if (token == XContentParser.Token.FIELD_NAME) { currentFieldName = parser.currentName(); } else if (token == XContentParser.Token.START_OBJECT) { if ("queries".equals(currentFieldName)) { queries.add(parseContext.parseInnerQuery()); } } else if (token == XContentParser.Token.START_ARRAY) { if ("queries".equals(currentFieldName)) { while (token != XContentParser.Token.END_ARRAY) { queries.add(parseContext.parseInnerQuery()); token = parser.nextToken(); } } } else { if ("boost".equals(currentFieldName)) { boost = parser.floatValue(); } else if ("tie_breaker".equals(currentFieldName) || "tieBreaker".equals(currentFieldName)) { tieBreaker = parser.floatValue(); } } } DisjunctionMaxQuery query = new DisjunctionMaxQuery(queries, tieBreaker); query.setBoost(boost); return query; }
From source file:org.elasticsearch.index.search.MultiMatchQueryTests.java
License:Apache License
public void testCrossFieldMultiMatchQuery() throws IOException { QueryShardContext queryShardContext = indexService.newQueryShardContext(); queryShardContext.setAllowUnmappedFields(true); Query parsedQuery = multiMatchQuery("banon").field("name.first", 2).field("name.last", 3).field("foobar") .type(MultiMatchQueryBuilder.Type.CROSS_FIELDS).toQuery(queryShardContext); try (Engine.Searcher searcher = indexService.getShard(0).acquireSearcher("test")) { Query rewrittenQuery = searcher.searcher().rewrite(parsedQuery); BooleanQuery.Builder expected = new BooleanQuery.Builder(); expected.add(new TermQuery(new Term("foobar", "banon")), BooleanClause.Occur.SHOULD); Query tq1 = new BoostQuery(new TermQuery(new Term("name.first", "banon")), 2); Query tq2 = new BoostQuery(new TermQuery(new Term("name.last", "banon")), 3); expected.add(new DisjunctionMaxQuery(Arrays.<Query>asList(tq1, tq2), 0f), BooleanClause.Occur.SHOULD); assertEquals(expected.build(), rewrittenQuery); }/*from ww w .j ava 2 s . co m*/ }