Fixed bug where BooleanQueryBuilder.java and BooleanFilterBuilder.java were mistakenly adding all child (and grandchild) clauses to the top node. A call to Element.getElementsByTagName was the offending code - this descends full depth rather than getting only immediate children which is the desired behaviour. Thanks to Jingkei Ly for spotting this bug.

git-svn-id: https://svn.apache.org/repos/asf/lucene/java/trunk@441667 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Mark Harwood 2006-09-08 21:45:14 +00:00
parent d0f5077d27
commit 6c53bc3c49
4 changed files with 50 additions and 13 deletions

View File

@ -11,6 +11,7 @@ import org.apache.lucene.xmlparser.DOMUtils;
import org.apache.lucene.xmlparser.FilterBuilder; import org.apache.lucene.xmlparser.FilterBuilder;
import org.apache.lucene.xmlparser.ParserException; import org.apache.lucene.xmlparser.ParserException;
import org.w3c.dom.Element; import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList; import org.w3c.dom.NodeList;
@ -28,16 +29,21 @@ public class BooleanFilterBuilder implements FilterBuilder {
public Filter getFilter(Element e) throws ParserException { public Filter getFilter(Element e) throws ParserException {
BooleanFilter bf=new BooleanFilter(); BooleanFilter bf=new BooleanFilter();
NodeList nl = e.getElementsByTagName("Clause"); NodeList nl = e.getChildNodes();
for(int i=0;i<nl.getLength();i++) for(int i=0;i<nl.getLength();i++)
{ {
Element clauseElem=(Element) nl.item(i); Node node = nl.item(i);
if(node.getNodeName().equals("Clause"))
{
Element clauseElem=(Element) node;
BooleanClause.Occur occurs=BooleanQueryBuilder.getOccursValue(clauseElem); BooleanClause.Occur occurs=BooleanQueryBuilder.getOccursValue(clauseElem);
Element clauseFilter=DOMUtils.getFirstChildOrFail(clauseElem); Element clauseFilter=DOMUtils.getFirstChildOrFail(clauseElem);
Filter f=factory.getFilter(clauseFilter); Filter f=factory.getFilter(clauseFilter);
bf.add(new FilterClause(f,occurs)); bf.add(new FilterClause(f,occurs));
} }
}
return bf; return bf;
} }

View File

@ -10,6 +10,7 @@ import org.apache.lucene.xmlparser.DOMUtils;
import org.apache.lucene.xmlparser.ParserException; import org.apache.lucene.xmlparser.ParserException;
import org.apache.lucene.xmlparser.QueryBuilder; import org.apache.lucene.xmlparser.QueryBuilder;
import org.w3c.dom.Element; import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList; import org.w3c.dom.NodeList;
@ -32,16 +33,21 @@ public class BooleanQueryBuilder implements QueryBuilder {
BooleanQuery bq=new BooleanQuery(DOMUtils.getAttribute(e,"disableCoord",false)); BooleanQuery bq=new BooleanQuery(DOMUtils.getAttribute(e,"disableCoord",false));
bq.setMinimumNumberShouldMatch(DOMUtils.getAttribute(e,"minimumNumberShouldMatch",0)); bq.setMinimumNumberShouldMatch(DOMUtils.getAttribute(e,"minimumNumberShouldMatch",0));
bq.setBoost(DOMUtils.getAttribute(e,"boost",1.0f)); bq.setBoost(DOMUtils.getAttribute(e,"boost",1.0f));
NodeList nl = e.getElementsByTagName("Clause");
NodeList nl = e.getChildNodes();
for(int i=0;i<nl.getLength();i++) for(int i=0;i<nl.getLength();i++)
{ {
Element clauseElem=(Element) nl.item(i); Node node = nl.item(i);
if(node.getNodeName().equals("Clause"))
{
Element clauseElem=(Element) node;
BooleanClause.Occur occurs=getOccursValue(clauseElem); BooleanClause.Occur occurs=getOccursValue(clauseElem);
Element clauseQuery=DOMUtils.getFirstChildOrFail(clauseElem); Element clauseQuery=DOMUtils.getFirstChildOrFail(clauseElem);
Query q=factory.getQuery(clauseQuery); Query q=factory.getQuery(clauseQuery);
bq.add(new BooleanClause(q,occurs)); bq.add(new BooleanClause(q,occurs));
} }
}
return bq; return bq;
} }

View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
This query was added to demonstrate nested boolean queries - there
was a bug in the XML parser which added ALL child <Clause> tags to
the top level tags ie. took child and grandchild elements instead
of just child elements. This was due to the use of the
Element.getElementsByTagName() call in BooleanQueryBuilder
-->
<BooleanQuery fieldName="contents">
<Clause occurs="should">
<BooleanQuery fieldName="contents">
<Clause occurs="must">
<TermQuery>doesNotExistButShouldBeOKBecauseOtherClauseExists</TermQuery>
</Clause>
</BooleanQuery>
</Clause>
<Clause occurs="should">
<TermQuery>bank</TermQuery>
</Clause>
</BooleanQuery>

View File

@ -150,6 +150,11 @@ public class TestParser extends TestCase {
Query q=parse("BooleanFilter.xml"); Query q=parse("BooleanFilter.xml");
dumpResults("Boolean filter", q, 5); dumpResults("Boolean filter", q, 5);
} }
public void testNestedBooleanQuery() throws ParserException, IOException
{
Query q=parse("NestedBooleanQuery.xml");
dumpResults("Nested Boolean query", q, 5);
}