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.ParserException;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
@ -28,15 +29,20 @@ public class BooleanFilterBuilder implements FilterBuilder {
public Filter getFilter(Element e) throws ParserException {
BooleanFilter bf=new BooleanFilter();
NodeList nl = e.getElementsByTagName("Clause");
NodeList nl = e.getChildNodes();
for(int i=0;i<nl.getLength();i++)
{
Element clauseElem=(Element) nl.item(i);
BooleanClause.Occur occurs=BooleanQueryBuilder.getOccursValue(clauseElem);
Node node = nl.item(i);
if(node.getNodeName().equals("Clause"))
{
Element clauseElem=(Element) node;
BooleanClause.Occur occurs=BooleanQueryBuilder.getOccursValue(clauseElem);
Element clauseFilter=DOMUtils.getFirstChildOrFail(clauseElem);
Filter f=factory.getFilter(clauseFilter);
bf.add(new FilterClause(f,occurs));
Element clauseFilter=DOMUtils.getFirstChildOrFail(clauseElem);
Filter f=factory.getFilter(clauseFilter);
bf.add(new FilterClause(f,occurs));
}
}
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.QueryBuilder;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
@ -32,15 +33,20 @@ public class BooleanQueryBuilder implements QueryBuilder {
BooleanQuery bq=new BooleanQuery(DOMUtils.getAttribute(e,"disableCoord",false));
bq.setMinimumNumberShouldMatch(DOMUtils.getAttribute(e,"minimumNumberShouldMatch",0));
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++)
{
Element clauseElem=(Element) nl.item(i);
BooleanClause.Occur occurs=getOccursValue(clauseElem);
Element clauseQuery=DOMUtils.getFirstChildOrFail(clauseElem);
Query q=factory.getQuery(clauseQuery);
bq.add(new BooleanClause(q,occurs));
Node node = nl.item(i);
if(node.getNodeName().equals("Clause"))
{
Element clauseElem=(Element) node;
BooleanClause.Occur occurs=getOccursValue(clauseElem);
Element clauseQuery=DOMUtils.getFirstChildOrFail(clauseElem);
Query q=factory.getQuery(clauseQuery);
bq.add(new BooleanClause(q,occurs));
}
}
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");
dumpResults("Boolean filter", q, 5);
}
public void testNestedBooleanQuery() throws ParserException, IOException
{
Query q=parse("NestedBooleanQuery.xml");
dumpResults("Nested Boolean query", q, 5);
}