Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

make the BaseQueryBuilder interface implement Clonable #1743

Closed
dnavre opened this issue Feb 28, 2012 · 7 comments
Closed

make the BaseQueryBuilder interface implement Clonable #1743

dnavre opened this issue Feb 28, 2012 · 7 comments

Comments

@dnavre
Copy link
Contributor

dnavre commented Feb 28, 2012

Because of this interface not implementing Clonable it's impossible to prepare and reuse parts of the query like this:

BoolQueryBuilder queryPart1 = boolQuery()
for(int i = 0; i < arr.size(); i++) {
    queryPart1.must(....);
}

BoolQueryBuilder mainQuery= boolQuery()
    .should(
        queryPart1
        .must(...)
    )
    .should(
        queryPart1
        .sould(...)
   );

I'm forced to create a new bool query at each point of reuse or externalize the creation of queryPart1 to a separate method and call it whenever i'm in need of that query part

@kimchy
Copy link
Member

kimchy commented Feb 28, 2012

You can safely reuse queryPart1 (in your code) in several places. Did you run into problems with it?

@dnavre
Copy link
Contributor Author

dnavre commented Feb 29, 2012

not exactly :) sorry, I was not clear enough.
What i mean is this: let's suppose i have imaginary conditions condition1, condition2 and condition3. and i need to find all rows satisfying query: (condition1 && condition 2) || (condition 1 and condition3). This is just an example, in real life the query i have is pretty damned complex and i need to reuse some of it's conditions in many places. So what happens when i use this code:

BoolQueryBuilder queryPart1 = boolQuery()
for(int i = 0; i < arr.size(); i++) {
    queryPart1.must(....); // building up condition1
}

BoolQueryBuilder mainQuery= boolQuery()
    .should(
        queryPart1 // reusing condition1
        .must(...) // adding condition2
    )
    .should(
        queryPart1 // reusing condition1
        .sould(...) // adding condition3
   );

in the end I'm ending up with this query: (condition1 && condition2) || (condition1 && condition2 && condition3)

what i'd like to be able to do is:

// building condition1
BoolQueryBuilder queryPart1 = boolQuery()
for(int i = 0; i < arr.size(); i++) {
    queryPart1.must(....);
}

BoolQueryBuilder mainQuery= boolQuery()
    .should(
        queryPart1.clone() // reusing condition1
        .must(...) // adding condition2
    )
    .should(
        queryPart1.clone() // reusing condition1
        .sould(...) // adding condition3
   );

this way i'm actually able to reuse the condition throughout the query.

@dnavre
Copy link
Contributor Author

dnavre commented Feb 29, 2012

If you're okay with it I can even try to implement this functionality myself and then do a pull request to you :)

@kimchy
Copy link
Member

kimchy commented Mar 1, 2012

I still don't understand why you would need it. You mean be able to clone a query, and then modify it? The problem with supporting clone is the semantics for more complex query builders, one that wrap a filter or another query.

@dnavre
Copy link
Contributor Author

dnavre commented Mar 15, 2012

sorry for the late reply.
I'd like to be able to clone the queries so i would be able to reuse a single query several times with different modifications.

lets suppose i have a boolQuery which i wrote and assigned to myBoolQuery var. I'm going to use it in several places in my final query. The first time i use it i just need to boost it, the second time i have an additional condition and the third time i have another condition. so the final result should look something like this:

boolQuery()
.should(myBoolQuery.boost(10F))
.should(myBoolQuery.must(/*blah */))
.should(myBoolQuery.must(/*another blah */);

This looks like what i'd really like to do but in reality it is not cause each time i call some method on myBoolQuery object it's changing the state of the object. What i'm ending with when using this query is the following conditional statement:

myPreparedCondition.boost()
|| (myPreparedCondition.boost() && must(/*blah*/))
|| (myPreparedCondition.boost() && must(/*blah*/) && must(/*another blah*/))

to get the query I originally wanted i need to wrap my prepared query in an additional bool query like this:

boolQuery()
.should(boolQuery().must(myBoolQuery).boost(10F))
.should(boolQuery().must(myBoolQuery).must(/*blah */))
.should(boolQuery().must(myBoolQuery).must(/*another blah */);

which in my opinion makes the code less readable and more cumbersome.

If the queries were clonable i would be able to write the query i originally wanted to have this way:

boolQuery()
.should(myBoolQuery.clone().boost(10F))
.should(myBoolQuery.clone().must(/*blah */))
.should(myBoolQuery.clone().must(/*another blah */);

another option to do this same thing is by making so that each query modifying method would not change the state of the existing query object but rather return a new query object with the modification inside of it. But I think this will be a damn lot harder to implement and I'm not even sure if this is something worth doing at all.

@dnavre dnavre closed this as completed Mar 13, 2014
@alex-lx
Copy link

alex-lx commented Oct 10, 2016

hi all, does this feature getting supported now? it seems muBollQuery is not clonable on version 2.4.0.

@Hronom
Copy link

Hronom commented Jun 22, 2021

Hello from 2020, this highly needed feature not available yet for reasons of "some semantic issues". But Solr have it SolrQuery.getCopy() and do deep copy.

Use case:
Imagine you write multi-query request and you have some common parts for each query. You want to re-use them, but not able to clone/copy the objects with deep copy. https://discuss.elastic.co/t/how-to-make-a-deepcopy-boolquerybuilder/211411/4

It's sad situation for me, since I understand that this will be never implemented here, even if it will be implemented now, I need this feature yesterday.

I hope developers of OpenSearch will be more friendly in the upcoming releases and will add such must have feature...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants