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

Additional criteria query options for JSON data types #56

Closed
bobbywarner opened this issue Jan 8, 2015 · 8 comments
Closed

Additional criteria query options for JSON data types #56

bobbywarner opened this issue Jan 8, 2015 · 8 comments

Comments

@bobbywarner
Copy link

It would be great to be able to use additional criteria query options. Most notably, ilike, to check for similar JSON values as opposed to just equals which is provided today.

@ilopmar
Copy link
Collaborator

ilopmar commented Jan 11, 2015

Hi Bobby,

which of these operators do you think we should implement? http://www.postgresql.org/docs/9.4/static/functions-json.html

@Sabst
Copy link

Sabst commented Aug 13, 2016

Hi,
I'm unsure whether a new operator is required but here is an example of what I would like to express using criteria:
select data from TestMapJson WHERE data->>'name' ILIKE '%iv%';
(inspired from PgJsonEqualsIntegration test)

I tried the obvious:
ilike "data->>'name'", "%iv%"
But this fails.

Is there a way to do this now ? (I'm using 4.6.1... still stuck with Grails 2.x)

@ilopmar
Copy link
Collaborator

ilopmar commented Aug 16, 2016

I don't know if this should work or not but maybe we need to create a new operator to do that, something like pgIlike "data-->'name', "%iv%"

@Sabst
Copy link

Sabst commented Aug 16, 2016

Ok, so no good surprise then.
Rather than having each time a new pg operator, do you see a more flexible way to handle this? Like using an advanced version of the current pgJsonHasFieldValue (with the operator provided as an argument)? Just wondering...

Now the immediate workaround is to bypass the plugin API... do you see a way to do this using criteria or do you think I have to turn the query into a SELECT?
What about defining my own operator outside of the pg-extensions plugin?

Thank you for your help.

@Sabst
Copy link

Sabst commented Aug 20, 2016

I added a pgJson criterion with the sql operator as an argument.
E.g. pgJson 'data', 'name', 'ilike', '%iv%'
The following will probably be clearer.
Am I missing anything? You already prepared everything for such a feature!

package net.kaleidos.hibernate.json

import spock.lang.Specification
import spock.lang.Unroll
import test.json.TestMapJson

class PgJsonIntegrationSpec extends Specification {

    def pgJsonTestSearchService

    @Unroll
    void 'Test equals finding value: #value with condition is ilike'() {
        setup:
            new TestMapJson(data: [name: 'Iván', lastName: 'López']).save(flush: true)
            new TestMapJson(data: [name: 'Alonso', lastName: 'Torres']).save(flush: true)
            new TestMapJson(data: [name: 'Iván', lastName: 'Pérez']).save(flush: true)

        when:
        def result = pgJsonTestSearchService.search('pgJson', 'data', 'name', value, 'ilike')

        then:
            result.size() == size
            result.every { it.data.name.matches "^(?i)${value.replace('%', '.*')}\$" }

        where:
            value  || size
            '%iv%' || 2
            'John' || 0
    }

    @Unroll
    void 'Test equals finding value: #value with condition equals'() {
        setup:
            new TestMapJson(data: [name: 'Iván', lastName: 'López']).save(flush: true)
            new TestMapJson(data: [name: 'Alonso', lastName: 'Torres']).save(flush: true)
            new TestMapJson(data: [name: 'Iván', lastName: 'Pérez']).save(flush: true)

        when:
        def result = pgJsonTestSearchService.search('pgJson', 'data', 'name', value, '=')

        then:
            result.size() == size
            result.every { it.data.name == value }

        where:
            value  || size
            'Iván' || 2
            'John' || 0
    }

    @Unroll
    void 'Test equals finding value: #value with condition does not equal'() {
        setup:
            new TestMapJson(data: [name: 'Iván', lastName: 'López']).save(flush: true)
            new TestMapJson(data: [name: 'Alonso', lastName: 'Torres']).save(flush: true)
            new TestMapJson(data: [name: 'Iván', lastName: 'Pérez']).save(flush: true)

        when:
        def result = pgJsonTestSearchService.search('pgJson', 'data', 'name', value, '<>')

        then:
            result.size() == size
            result.every { it.data.name != value }

        where:
            value  || size
            'Iván' || 1
            'John' || 3
    }

}

@ilopmar
Copy link
Collaborator

ilopmar commented Aug 20, 2016

This looks good! If everything is working and you have tests please submit a PR.

I think in a couple of weeks I'll have some spare time. There are some PRs pending that I need to review and merge and I'm delaying this too much. Sorry about this.

Thanks for your contribution.

@Sabst
Copy link

Sabst commented Aug 20, 2016

Not really ready for a PR but I will consider it.
More step-back will be required to allow more PG Json/Jsonb/... options.
Ideally the plugin should provide access to all those great PG features!

@ilopmar
Copy link
Collaborator

ilopmar commented Nov 3, 2016

PR #95 has been merged and ported also to Grails 3. I've released versions 4.6.2 for Grails 2 and 4.6.8 for Grails 3 with this new json criteria.

Closing this issue.

@ilopmar ilopmar closed this as completed Nov 3, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants