The use cases that are important to me for my specific needs.

Generate a query string that can be passed to SolrJ's SolrQuery(String q).

During query generation the properties of the query can be manipulated.

For example:

title:"pink panther"^2 could be manipulated to be something different such as 
+title:"pink panther"~2^=1

If there are two queries be able to group them together.

title:"pink panther"~2 title:"war and peace"^3

Is grouped into:

(title:"pink panther"~2 +title:"war and peace"^3)



And then that grouping can be manipulated to be something different, such as:

+(title:"pink panther" title:"war and peace")^=2

I realize that the outer MUST is not needed, but If I nest that into another 
group then it is applicable such as:

( title:"star wars" +(title:"pink panther" title:"war and peace")^=2 )



Here there are two sub groups:

( field1:"A" field2:"B")^1 ( field1:"C" field2:"D")^=2

These sub groups can be wrapped inside another group and manipulated:

( +( field1:"A" field2:"B") +( field1:"C" field2:"D") )^3

And then that larger group may get another sub gruop added like:

( +( field1:"A" field2:"B") +( field1:"C" field2:"D") ( field3: "E") )^0.333

And then I decide to remove a sub group and end up with something that looks 
like this:

( +( field1:"A" field2:"B") ( field3: "E") )^0.5



And so on and so forth.


Then after I have composed all of the query objects I finally call something to 
convert that to a string to pass to SolrQuery(String q)


The code for this Java "container" is fairly simple, thus I refered to it as a 
Simple Query Generator.

However, what it does allows for the creation of complex queries.


So, as this progresses, whatever the solution may be, I would like my use cases 
to be considered.

Geoffrey


> On Aug 20, 2024, at 4:49 PM, Uwe Schindler <u...@thetaphi.de> wrote:
> 
> +1: Thanks for this writeup, Jan!
> 
> Am 20.08.2024 um 22:49 schrieb Jan Høydahl:
>> Having written tons of Java client code for querying elasticsearch, one 
>> thing I
>> appreciate with the various QueryBuilders is how closely they map to the 
>> actual
>> Lucene Query objects being the end result. Also, they are nicely composable,
>> and of course map almost 1:1 to ES JSON query dsl.
>> 
>> So if we want to evolve SolrJ's ability to construct complex queries, I'd 
>> propose
>> we couple the SolrJ builders to our JSON Query DSL and take the opportunity 
>> to
>> evolving, fixing and documenting that DSL in the process.
>> 
>> It would be a bonus if builders could output/serialize to legacy-query-string
>> as an option, but supporting only legacy would be a strange design choice.
>> 
>> Jan
>> 
>>> 20. aug. 2024 kl. 22:10 skrev Gus Heck <gus.h...@gmail.com>:
>>> 
>>> Also if expressed as xml the lucene classes can be sent to solr (not sure
>>> if we have a tool to express them as xml however)
>>> 
>>> https://solr.apache.org/guide/solr/latest/query-guide/other-parsers.html#xml-query-parser
>>> 
>>> On Tue, Aug 20, 2024 at 1:11 PM Mike Drob <md...@apache.org> wrote:
>>> 
>>>> 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
>>>>> 
>>>>> 
>>> 
>>> -- 
>>> http://www.needhamsoftware.com (work)
>>> https://a.co/d/b2sZLD9 (my fantasy fiction book)
>> 
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: dev-unsubscr...@solr.apache.org
>> For additional commands, e-mail: dev-h...@solr.apache.org
>> 
> -- 
> Uwe Schindler
> Achterdiek 19, D-28357 Bremen
> https://www.thetaphi.de
> eMail: u...@thetaphi.de
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscr...@solr.apache.org
> For additional commands, e-mail: dev-h...@solr.apache.org
> 


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@solr.apache.org
For additional commands, e-mail: dev-h...@solr.apache.org

Reply via email to