Hello,

I'm trying to implement a query language with ao. AND and OR
operators for Lucene. I can get the AND operator to work
by mapping it to a BooleanQuery with only required terms.
However, when I  try to implement the OR operator by
mapping it to a BooleanQuery with non required terms,
it happens that documents that match the AND like query:

+word1 +word2

do not match the OR like query:

word1 word2

This happens to the very first doc in the test database
below.

Strange enough this behaviour is not inconsistent with
the documentation for BooleanQuery for non required
terms. From the API java doc: "required means
that documents which do not match this sub-query will
not match the boolean query."

(I'm using the WhitespaceAnalyzer for the queries and for
indexing the test db.)

I can only assume that I am doing something wrong.
What is the right way to implement 'all docs that have
at least one of'  (ie. OR like) queries in Lucene?

Thanks,
Paul


P.S. The source code for the test is inline below. It can be
put in the file
src/test/org/apache/lucene/TestSearchL.java
of a cvs working copy after which 'ant test' shows
two passing test cases for AND (test03And..), and
two failing test cases for OR (test04Or..).
The other tests have been disabled by changing
their name from test... to tst.., these pass normally
when enabled.
The code was derived from TestSearch.java, and I left
out the licence here for brevity:


package org.apache.lucene;

import junit.framework.TestCase;
import junit.framework.TestSuite;
import junit.textui.TestRunner;

import org.apache.lucene.store.Directory;
import org.apache.lucene.store.RAMDirectory;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.analysis.WhitespaceAnalyzer;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Searcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.HitCollector;
import org.apache.lucene.queryParser.QueryParser;

public class TestSearchL extends TestCase {
    public static void main(String args[]) {
        TestRunner.run(new TestSuite(TestSearchL.class));
    }

    final String fieldName = "contents";

    String[] docs1 = {
        "word1 word2 word3",
        "word4 word5",
        "ord1 ord2 ord3",
        "orda1 orda2 orda3 word2 worda3",
        "a c e a b c"
    };

    Directory dBase1 = createDb(docs1);

    public void normalTest1(String query, int[] expdnrs) throws Exception {
        new NormalQueryTest( query, expdnrs, dBase1, docs1).doTest();
    }

    public void tst02Terms01() throws Exception {
        int[] expdnrs = {0}; normalTest1( "word1", expdnrs);
    }
    public void tst02Terms02() throws Exception {
        int[] expdnrs = {0, 1, 3}; normalTest1( "word*", expdnrs);
    }
    public void tst02Terms03() throws Exception {
        int[] expdnrs = {2}; normalTest1( "ord2", expdnrs);
    }
    public void tst02Terms04() throws Exception {
        int[] expdnrs = {}; normalTest1( "gnork*", expdnrs);
    }
    public void tst02Terms05() throws Exception {
        int[] expdnrs = {0, 1, 3}; normalTest1( "wor*", expdnrs);
    }
    public void tst02Terms06() throws Exception {
        int[] expdnrs = {}; normalTest1( "ab", expdnrs);
    }

    public void test03And01() throws Exception {
        int[] expdnrs = {0}; normalTest1( "+word1 +word2", expdnrs);
    }
    public void test03And02() throws Exception {
        int[] expdnrs = {3}; normalTest1( "+word* +ord*", expdnrs);
    }

    public void test04Or01() throws Exception {
        int[] expdnrs = {0, 3}; normalTest1( "word1 word2", expdnrs);
    }
    public void test04Or02() throws Exception {
        int[] expdnrs = {0, 1, 2, 3}; normalTest1( "word* ord*", expdnrs);
    }

    class NormalQueryTest {
        String queryText;
        final int[] expectedDocNrs;
        Directory dBase;
        String[] docs;

        NormalQueryTest(String qt, int[] expdnrs, Directory db, String[] documents) {
            queryText = qt;
            expectedDocNrs = expdnrs;
            dBase = db;
            docs = documents;
        }

        public void doTest() throws Exception {
            Analyzer analyzer = new WhitespaceAnalyzer();
            QueryParser parser = new QueryParser(fieldName, analyzer);
            Query query = parser.parse(queryText);

            System.out.println("QueryL: " + queryText);
            System.out.println("ParsedL: " + query.toString());
            TestCollector tc = new TestCollector();
            Searcher searcher = new IndexSearcher(dBase);
            try {
                searcher.search(query, tc);
            } finally {
                searcher.close();
            }
            tc.checkNrHits();
        }

        class TestCollector extends HitCollector {
            int totalMatched;

            TestCollector() { totalMatched = 0; }

            public void collect(int docNr, float score) {
                System.out.println(docNr + " '" + docs[docNr] + "': " + score);
                assertTrue(queryText + ": positive score", score > 0.0);
                assertTrue(queryText + ": too many hits", totalMatched < 
expectedDocNrs.length);
                assertEquals(queryText + ": doc nr for hit " + totalMatched, 
expectedDocNrs[totalMatched], docNr);
                totalMatched++;
            }

            void checkNrHits() { assertEquals(queryText + ": nr of hits", 
expectedDocNrs.length, totalMatched); }
        }
    }

    private Directory createDb(String[] docs) {
        try {
            Directory directory = new RAMDirectory();
            Analyzer analyzer = new WhitespaceAnalyzer();
            IndexWriter writer = new IndexWriter(directory, analyzer, true);
            for (int j = 0; j < docs.length; j++) {
                Document d = new Document();
                d.add(Field.Text(fieldName, docs[j]));
                writer.addDocument(d);
            }
            writer.close();
            return directory;
        } catch (java.io.IOException ioe) {
            throw new Error(ioe);
        }
    }
}



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to