At the risk of sounding ignorant, what is the advantage of this over using Lucene classes to programmatically build queries and then toString those? It's not a single class, but the lucene search package has always seemed pretty straightforward to me. https://lucene.apache.org/core/9_7_0/core/org/apache/lucene/search/package-summary.html#query https://lucene.apache.org/core/9_7_0/core/org/apache/lucene/search/Query.html
If the goal is human readable query methods, I had previously done some of the work in the opposite direction (matching queries to descriptions instead of descriptions to queries) in test framework's QueryMatcher, might be worth comparing against. https://github.com/apache/solr/blob/main/solr/test-framework/src/java/org/apache/solr/util/QueryMatchers.java On Tue, Aug 20, 2024 at 11:07 AM David Smiley <dsmi...@apache.org> wrote: > Let's bikeshed before you write code, okay? Otherwise you potentially > waste time and/or grow attached to sunk costs. > > Feedback: > * avoid the word "term"; it already has Lucene definition and a Solr > query parser but you're using it in a way that isn't either. I > recommend simply for "fieldQuery" -- these queries target specific > fields after all. > * Can we avoid top level classes that the user must know about; > instead having one class -- QueryBuilder (or named QueryStringBuilder) > with factory methods that are easily discoverable? Not a huge deal. > * Instead of "Group", lets acknowledge these map to a BooleanQuery so > I think "bool" in some way should be used instead. Some bool builder > can then have must() should() filter() methods without needing an > enum. > * Can't import any Lucene things > > I'll add examples below of my feedback ideas. > > On Tue, Aug 20, 2024 at 11:04 AM Geoffrey Slinker > <geoffrey_slin...@yahoo.com.invalid> wrote: > > > Instantiate a Term and set the values and call toString to get a string > that can be used in a Standard Solr Query. > > Term term = new Term("pink panther").withBoost(1.5f); > > term. toString() > > > > Output: "pink panther"^1.5 > > > > Term term = new Term("title", "pink panther").withBoost(1.5f); > > term. toString() > > > > Output: title:"pink panther"^1.5 > > final QueryStringBuilder B = new QueryStringBuilder(potential > options); // immutable > B.field("title", "ping panther").withBoost(1.5f).toString(); > > > > TermGroup group = new TermGroup().with(Occur. > MUST).withBoost(1.4f); > > group. addTerm(new Term("foo", "bar").withProximity(1)); > > > > String query = group. toString(); > > > > Output: +( foo:bar~1 )^1.4 > > the outer MUST is pointless but I'll recreate anyway: > > final QueryStringBuilder B = new QueryStringBuilder(potential > options); // immutable > B.bool().must(B.fieldFuzzy("foo", "bar", 1).withBoost(1.4)).toString(); > > > Example: > > TermGroup group = new TermGroup().withConstantScore(5.0f); > > group. addTerm(new Term("foo", "bar").withProximity(1)); > > > > String query = group. toString(); > > > > Output: ( foo:bar~1 )^=5 > > final QueryStringBuilder B = new QueryStringBuilder(potential > options); // immutable > B.fieldFuzzy("foo", "bar", 1).withConstantScore(5.0f).toString(); > // no "group" terminology necessary > > > Instead of using string manipulation to create complex query strings the > TermGroup allows complex queries to be built inside an object model that > can be more easily changed. > > If you need to generate a query like this: > > +( > > ( > > title:"Grand Illusion"~1 > > title:"Paradise Theatre"~1 > > )^0.3 > > ( > > title:"Night At The Opera"~1 > > title:"News Of The World"~1 > > )^0.3 > > ( > > title:"Van Halen"~1 > > title:1984~1 > > )^0.3 > > ) > > > > > > The code to do so is as simple this: > > > > TermGroup group = new TermGroup().with(Occur. MUST); > > > > TermGroup favoriteStyx = group. addGroup().withBoost(0.3f); > > TermGroup favoriteQueen = group. addGroup().withBoost(0.3f); > > TermGroup favoriteVanHalen = group. addGroup().withBoost(0.3f); > > > > favoriteStyx. addTerm(new Term("title","Grand > Illusion").with(Occur. SHOULD).withProximity(1)); > > favoriteStyx. addTerm(new Term("title","Paradise > Theatre").with(Occur. SHOULD).withProximity(1)); > > > > favoriteQueen. addTerm(new Term("title","Night At The > Opera").with(Occur. SHOULD).withProximity(1)); > > favoriteQueen. addTerm(new Term("title","News Of The > World").with(Occur. SHOULD).withProximity(1)); > > > > favoriteVanHalen. addTerm(new Term("title","Van > Halen").with(Occur. SHOULD).withProximity(1)); > > favoriteVanHalen. addTerm(new Term("title","1984").with(Occur. > SHOULD).withProximity(1)); > > > > // again, the outer bool MUST is pointless but will recreate your example > > final QueryStringBuilder B = new QueryStringBuilder(potential > options); // immutable > > var favoriteStyx = B.bool(); > favoriteStyx.should(B.field("title", "Grand Illusion").withProximity(1)); > favoriteStyx.should(B.field("title", "Paradise Theater").withProximity(1)); > > var favoriteQueen = B.bool(); > favoriteQueen.should(B.field("title", "Night At The > Opera").withProximity(1)); > favoriteQueen.should(B.field("title", "News Of The > World").withProximity(1)); > > var favoriteVanHalen = B.bool(); > favoriteVanHalen.should(B.field("title", "Van Halen").withProximity(1)); > favoriteVanHalen.should(B.field("title", "1984").withProximity(1)); > > B.bool().must( // pointless wrap > B.bool().should(favoriteStyx.withBoost(0.3f)) > .should(favoriteQueen.withBoost(0.3f)) > .should(favoriteVanHalen.withBoost(0.3f)) > ).toString(); > > --- > If we imagine plausibly expanding support to write Solr JSON as an > alternative, then it could affect the code choices. Like > toSolrLuceneSyntax() and toSolrQueryDsl(). > > --------------------------------------------------------------------- > To unsubscribe, e-mail: dev-unsubscr...@solr.apache.org > For additional commands, e-mail: dev-h...@solr.apache.org > >