From 36bc3d70bb37b2db456821fd96a306fb69b11d5f Mon Sep 17 00:00:00 2001 From: Robert Muir Date: Sun, 22 Apr 2012 21:28:15 +0000 Subject: [PATCH] LUCENE-4004: add DisjunctionMaxQuery support to the xml query parser git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1328981 13f79535-47bb-0310-9956-ffa450edef68 --- lucene/CHANGES.txt | 3 + .../lucene/search/DisjunctionMaxQuery.java | 18 +++++- .../lucene/queryparser/xml/CoreParser.java | 1 + .../builders/DisjunctionMaxQueryBuilder.java | 60 +++++++++++++++++++ .../queryparser/xml/DisjunctionMaxQuery.xml | 24 ++++++++ .../lucene/queryparser/xml/TestParser.java | 12 ++++ 6 files changed, 117 insertions(+), 1 deletion(-) create mode 100644 lucene/queryparser/src/java/org/apache/lucene/queryparser/xml/builders/DisjunctionMaxQueryBuilder.java create mode 100644 lucene/queryparser/src/test/org/apache/lucene/queryparser/xml/DisjunctionMaxQuery.xml diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt index 7f1cffd29bf..df73e051569 100644 --- a/lucene/CHANGES.txt +++ b/lucene/CHANGES.txt @@ -843,6 +843,9 @@ New features analysis/ module. The 'smartcn' and 'stempel' components now depend on 'common'. (Chris Male, Robert Muir) +* LUCENE-4004: Add DisjunctionMaxQuery support to the xml query parser. + (Benson Margulies via Robert Muir) + Optimizations * LUCENE-2588: Don't store unnecessary suffixes when writing the terms diff --git a/lucene/core/src/java/org/apache/lucene/search/DisjunctionMaxQuery.java b/lucene/core/src/java/org/apache/lucene/search/DisjunctionMaxQuery.java index f1b9feed6b3..87c7ae833d2 100644 --- a/lucene/core/src/java/org/apache/lucene/search/DisjunctionMaxQuery.java +++ b/lucene/core/src/java/org/apache/lucene/search/DisjunctionMaxQuery.java @@ -78,15 +78,30 @@ public class DisjunctionMaxQuery extends Query implements Iterable { /** Add a collection of disjuncts to this disjunction * via Iterable + * @param disjuncts a collection of queries to add as disjuncts. */ public void add(Collection disjuncts) { this.disjuncts.addAll(disjuncts); } - /** An Iterator over the disjuncts */ + /** @return An Iterator over the disjuncts */ public Iterator iterator() { return disjuncts.iterator(); } + + /** + * @return the disjuncts. + */ + public ArrayList getDisjuncts() { + return disjuncts; + } + + /** + * @return tie breaker value for multiple matches. + */ + public float getTieBreakerMultiplier() { + return tieBreakerMultiplier; + } /** * Expert: the Weight for DisjunctionMaxQuery, used to @@ -279,4 +294,5 @@ public class DisjunctionMaxQuery extends Query implements Iterable { + disjuncts.hashCode(); } + } diff --git a/lucene/queryparser/src/java/org/apache/lucene/queryparser/xml/CoreParser.java b/lucene/queryparser/src/java/org/apache/lucene/queryparser/xml/CoreParser.java index 3b19f870b53..bcbccd66646 100644 --- a/lucene/queryparser/src/java/org/apache/lucene/queryparser/xml/CoreParser.java +++ b/lucene/queryparser/src/java/org/apache/lucene/queryparser/xml/CoreParser.java @@ -75,6 +75,7 @@ public class CoreParser implements QueryBuilder { queryFactory.addBuilder("MatchAllDocsQuery", new MatchAllDocsQueryBuilder()); queryFactory.addBuilder("BooleanQuery", new BooleanQueryBuilder(queryFactory)); queryFactory.addBuilder("NumericRangeQuery", new NumericRangeQueryBuilder()); + queryFactory.addBuilder("DisjunctionMaxQuery", new DisjunctionMaxQueryBuilder(queryFactory)); if (parser != null) { queryFactory.addBuilder("UserQuery", new UserInputQueryBuilder(parser)); } else { diff --git a/lucene/queryparser/src/java/org/apache/lucene/queryparser/xml/builders/DisjunctionMaxQueryBuilder.java b/lucene/queryparser/src/java/org/apache/lucene/queryparser/xml/builders/DisjunctionMaxQueryBuilder.java new file mode 100644 index 00000000000..22c842e230e --- /dev/null +++ b/lucene/queryparser/src/java/org/apache/lucene/queryparser/xml/builders/DisjunctionMaxQueryBuilder.java @@ -0,0 +1,60 @@ +package org.apache.lucene.queryparser.xml.builders; +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import org.apache.lucene.queryparser.xml.DOMUtils; +import org.apache.lucene.queryparser.xml.ParserException; +import org.apache.lucene.queryparser.xml.QueryBuilder; +import org.apache.lucene.search.DisjunctionMaxQuery; +import org.apache.lucene.search.Query; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +/** + * Build a DisjunctionMaxQuery. + */ +public class DisjunctionMaxQueryBuilder implements QueryBuilder { + + private final QueryBuilder factory; + + public DisjunctionMaxQueryBuilder(QueryBuilder factory) { + this.factory = factory; + } + + /* (non-Javadoc) + * @see org.apache.lucene.xmlparser.QueryObjectBuilder#process(org.w3c.dom.Element) + */ + + public Query getQuery(Element e) throws ParserException { + float tieBreaker = DOMUtils.getAttribute(e, "tieBreaker", 0.0f); + DisjunctionMaxQuery dq = new DisjunctionMaxQuery(tieBreaker); + dq.setBoost(DOMUtils.getAttribute(e, "boost", 1.0f)); + + NodeList nl = e.getChildNodes(); + for (int i = 0; i < nl.getLength(); i++) { + Node node = nl.item(i); + if (node instanceof Element) { // all elements are disjuncts. + Element queryElem = (Element) node; + Query q = factory.getQuery(queryElem); + dq.add(q); + } + } + + return dq; + } +} diff --git a/lucene/queryparser/src/test/org/apache/lucene/queryparser/xml/DisjunctionMaxQuery.xml b/lucene/queryparser/src/test/org/apache/lucene/queryparser/xml/DisjunctionMaxQuery.xml new file mode 100644 index 00000000000..eb478165205 --- /dev/null +++ b/lucene/queryparser/src/test/org/apache/lucene/queryparser/xml/DisjunctionMaxQuery.xml @@ -0,0 +1,24 @@ + + + + + merger + + verger + + \ No newline at end of file diff --git a/lucene/queryparser/src/test/org/apache/lucene/queryparser/xml/TestParser.java b/lucene/queryparser/src/test/org/apache/lucene/queryparser/xml/TestParser.java index abbb4045e4d..e1b5c1623f2 100644 --- a/lucene/queryparser/src/test/org/apache/lucene/queryparser/xml/TestParser.java +++ b/lucene/queryparser/src/test/org/apache/lucene/queryparser/xml/TestParser.java @@ -27,6 +27,7 @@ import org.apache.lucene.document.TextField; import org.apache.lucene.index.AtomicReaderContext; import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.IndexWriter; +import org.apache.lucene.search.DisjunctionMaxQuery; import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.search.Query; import org.apache.lucene.search.ScoreDoc; @@ -104,6 +105,17 @@ public class TestParser extends LuceneTestCase { Query q = parse("BooleanQuery.xml"); dumpResults("BooleanQuery", q, 5); } + + public void testDisjunctionMaxQueryXML() throws ParserException, IOException { + Query q = parse("DisjunctionMaxQuery.xml"); + assertTrue(q instanceof DisjunctionMaxQuery); + DisjunctionMaxQuery d = (DisjunctionMaxQuery)q; + assertEquals(0.0f, d.getTieBreakerMultiplier(), 0.0001f); + assertEquals(2, d.getDisjuncts().size()); + DisjunctionMaxQuery ndq = (DisjunctionMaxQuery) d.getDisjuncts().get(1); + assertEquals(1.2f, ndq.getTieBreakerMultiplier(), 0.0001f); + assertEquals(1, ndq.getDisjuncts().size()); + } public void testRangeFilterQueryXML() throws ParserException, IOException { Query q = parse("RangeFilterQuery.xml");