Doug, That approach does not work. I could not find an approach that would work with the built-in classes, although of course there might be one. The problem has two components: coord and the fact that BooleanQuery's sum their clause scores to compute the final score. The latter is not easily overridden. Specifically,
title:(albino elephant)^4 description:(albino elephant) still has the problem that a result with albino in the title and albino in the description gets the same score as a result with albino in the title and elephant in the description (assuming tf and idf scores are not relevant, and if they are they may make the problem worse rather than better). In fact the query above, without overriding coord, is equivalent to (title:albino title:elephant description:albino description:elephant) which makes the root cause of the problem apparent (no distinction between the same term in different fields vs. different terms in different fields). The coord override improves the score for the case of single fields that contain both terms, but still does not differentiate between the cases of same term in different fields and different terms in different fields. FYI, MaxDisjunctionQuery has made an enormous improvement in the quality of my query results, and I have strong reason to believe the same would be true in most other domains (more on that coming in the idf^2 discussion). In terms of the albino elephant example, the query above was putting all the albino animals except elephants above the albino elephants, while the query with an outer BooleanQuery and inner MaxDisjunctionQuery's ( (title:albino^4 | description:albino)~0.1 (title:elephant^4 | description:elephant)~0.1 ) properly puts the albino elephants on top. Chuck > -----Original Message----- > From: Doug Cutting [mailto:[EMAIL PROTECTED] > Sent: Wednesday, October 13, 2004 9:57 AM > To: Lucene Developers List > Subject: Re: Contribution: better multi-field searching > > Chuck Williams wrote: > > The issue is this. Imagine you have two fields, title and document, > > both of which you want to search with simple queries like: albino > > elephant. There are two general approaches, either a) create a combined > > field that concatenates the two individual fields, or b) expand the > > simple query into a BooleanQuery that searches for each term in both > > fields. > > > > With approach a), you lose the flexibility to set separate boost factors > > on the individual fields. I wanted title to be much more important than > > description for ranking results, and wanted to control this explicitly, > > as length norm was not always doing the right thing; e.g., descriptions > > are not always long. > > > > With approach b) you run into another problem. Suppose the example > > query is expanded into (title:albino description:albino title:elephant > > description:elephant). Then, assuming tf/idf doesn't affect ranking, a > > document with albino in both title and description will score the same > > as a document with albino in title and elephant in description. The > > latter document for most applications is much better since it matches > > both query terms. If albino is the more important term according to > > idf, then the less desirable documents (albino in both fields) will rank > > consistently ahead of the albino elephants (which is what was happening > > to me, yielding horrible results). > > Another way to handle this would be to generate a query like:[Chuck Williams] Y > > title:(albino elephant) description(albino elephant) > > In this case the coord factor would boost titles and descriptions which > contained both terms. You may or may not want to disable the coord > factor for the outer query, which can be done with: > > BooleanQuery title = new BooleanQuery(); > title.add(new TermQuery(new Term("title", "albino")), false, false); > title.add(new TermQuery(new Term("title", "elephant")), false, false); > > BooleanQuery desc = new BooleanQuery(); > desc.add(new TermQuery(new Term("desc", "albino")), false, false); > desc.add(new TermQuery(new Term("desc", "elephant")), false, false); > > BooleanQuery outer = new BooleanQuery() { > public getSimilarity() { > new DefaultSimilarity() { > public coord(int overlap, int length) { return 1.0f; } > } > } > }; > outer.add(title, false, false); > outer.add(desc, false, false); > > In general, doesn't coord() handle this situation? > > Also, you can separately boost title and desc here, if you like: > > title:(albino elephant)^4.0 description(albino elephant) > > or > > title.boost(4.0f); > > > > Doug > > --------------------------------------------------------------------- > To unsubscribe, e-mail: [EMAIL PROTECTED] > For additional commands, e-mail: [EMAIL PROTECTED] --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]