Struggling with 'complex' query format using Groovy API


(Jondow) #1

I know this will seem quite pathetic, but I'm struggling to mentally
map the json query format shown in the online docs to the equivalent
Groovy syntax for the builder. I've Googled, and also looked at the
test code in the master code that I downloaded, but while they give
examples of fairly simple 'term' searches, none show an example of
searching a more complex mapping.

I have the following as an example of the JSON that I've indexed. If
you take the common index example from the docs, namely:

def indexR = client.index {
index "test"
type "type1"
id "1"
source {
test = "value"
complex {
value1 = "value1"
value2 = "value2"
}
}
}

How would you search for all type1's with a 'complex' value1 field
containing "value1"? As in, what would the Groovy code look like? I
did a:

    def search = client.search {
        indices "test"
        types "type1"
        source {
            query {
                field {
                    complex.value1 = "value1"
                }
            }
        }
    }

But the compiler complains that:
org.codehaus.groovy.grails.web.taglib.exceptions.GrailsTagException:
Tag [null] is missing required attribute [name] or [field]
at xxxxxxxxxxxxxxxxxxx.SearchController
$_closure2_closure6_closure8_closure9.doCall(SearchController.groovy:
53)
at xxxxxxxxxxxxxxxxxxx.SearchController
$_closure2_closure6_closure8_closure9.doCall(SearchController.groovy)
at
org.elasticsearch.groovy.common.xcontent.GXContentBuilder.handleClosureNode(GXContentBuilder.groovy:
157)
at org.elasticsearch.groovy.common.xcontent.GXContentBuilder.this
$2$handleClosureNode(GXContentBuilder.groovy)
at org.elasticsearch.groovy.common.xcontent.GXContentBuilder$this
$2$handleClosureNode.callCurrent(Unknown Source)
at
org.elasticsearch.groovy.common.xcontent.GXContentBuilder.invokeMethod(GXContentBuilder.groovy:
119)
at xxxxxxxxxxxxxxxxxxxx.SearchController
$_closure2_closure6_closure8.doCall(SearchController.groovy:52)


(Clinton Gormley) #2

How would you search for all type1's with a 'complex' value1 field
containing "value1"? As in, what would the Groovy code look like? I
did a:

    def search = client.search {
        indices "test"
        types "type1"
        source {
            query {
                field {
                    complex.value1 = "value1"
                }
            }
        }
    }

I don't know groovy syntax, but do you not just need to put quotes
around complex.value1 ?

clint


(Jondow) #3

Hmm, no it seems my main error is misreading the Query API ... there
is no 'field' filter for queries. There is a 'fields', but that's to
indicate what you want in the returned result.

I need to do a 'term' query I think. Though I'm still having trouble
targeting the value1 field as per the example above. So any help would
still be appreciated. :frowning:

On Jun 10, 3:47 pm, Clinton Gormley clin...@iannounce.co.uk wrote:

How would you search for all type1's with a 'complex' value1 field
containing "value1"? As in, what would the Groovy code look like? I
did a:

    def search = client.search {
        indices "test"
        types "type1"
        source {
            query {
                field {
                    complex.value1 = "value1"
                }
            }
        }
    }

I don't know groovy syntax, but do you not just need to put quotes
around complex.value1 ?

clint


(Jondow) #4

No, that's not it. At first I thought I had found the error (and even
posted a reply here that seems to have gone missing) that there was no
'field' type query - this is mainly because of how I was looking at
the docs, and also because when I reduced the query to a term query,
it compiled (but didn't work). Anyway, long story short, there IS a
field type query which is a shorthand for the query_term with a
default field. So I'm back to square one and unable to get the Groovy
incarnation to work. :frowning:

On Jun 10, 3:47 pm, Clinton Gormley clin...@iannounce.co.uk wrote:

How would you search for all type1's with a 'complex' value1 field
containing "value1"? As in, what would the Groovy code look like? I
did a:

    def search = client.search {
        indices "test"
        types "type1"
        source {
            query {
                field {
                    complex.value1 = "value1"
                }
            }
        }
    }

I don't know groovy syntax, but do you not just need to put quotes
around complex.value1 ?

clint


(Jondow) #5

Ok, so I figured out part of the problem. It was actually a red
herring, related to the use of the 'field' keyword keywork within a
Grails controller context. That part is now sorted having moved the
search to a Grails service, but I'm still not able to target nested
information. In this case my JSON is structured as follows:

{
name1 = value1
name2 = value2
software = [{'name':'Adobe Reader', 'version': '1.0'},
{'name':'Mozilla Firefox', 'version':'4.0'}]
}

How would I target searching for software with the name 'adobe'? What
would the JSON look like for that?


(Shay Banon) #6

The query itself can look like: { "text" : { "software.name" : "adobe" } }

On Friday, June 10, 2011 at 8:08 PM, Jondow wrote:

Ok, so I figured out part of the problem. It was actually a red
herring, related to the use of the 'field' keyword keywork within a
Grails controller context. That part is now sorted having moved the
search to a Grails service, but I'm still not able to target nested
information. In this case my JSON is structured as follows:

{
name1 = value1
name2 = value2
software = [{'name':'Adobe Reader', 'version': '1.0'},
{'name':'Mozilla Firefox', 'version':'4.0'}]
}

How would I target searching for software with the name 'adobe'? What
would the JSON look like for that?


(Jondow) #7

I still can't get this to work in Groovy. I've tried every possible
permutation of the syntax to match Shay's response, but all to no
avail. So for instance:

    return client.search {
        indices "test"
        types "type1"
        source {
            text = {
                ["software.name": "Adobe"]
            }
        }
    }

or:

    return client.search {
        indices "test"
        types "type1"
        source {
            query {
                text {
                    ["software.name": "Adobe"]
                }
            }
        }
    }

to name but two options I've tried. They all fail with:

SearchParseException[[test][4]: from[-1],size[-1]: Parse Failure [No
parser for element [text]]]; }

So Shay, any idea how to fulfill your suggestion in Groovy? :frowning: This
is as much for me to understand how to do things in Groovy as it is to
solve this particular example.

On Jun 12, 9:22 am, Shay Banon shay.ba...@elasticsearch.com wrote:

The query itself can look like: { "text" : { "software.name" : "adobe" } }

On Friday, June 10, 2011 at 8:08 PM, Jondow wrote:

Ok, so I figured out part of the problem. It was actually a red
herring, related to the use of the 'field' keyword keywork within a
Grails controller context. That part is now sorted having moved the
search to a Grails service, but I'm still not able to target nested
information. In this case my JSON is structured as follows:

{
name1 = value1
name2 = value2
software = [{'name':'Adobe Reader', 'version': '1.0'},
{'name':'Mozilla Firefox', 'version':'4.0'}]
}

How would I target searching for software with the name 'adobe'? What
would the JSON look like for that?


(Shay Banon) #8

Which elasticsearch version are you using? text query was added in 0.16.1.

On Monday, June 13, 2011 at 3:56 PM, Jondow wrote:

I still can't get this to work in Groovy. I've tried every possible
permutation of the syntax to match Shay's response, but all to no
avail. So for instance:

return client.search {
indices "test"
types "type1"
source {
text = {
["software.name (http://software.name)": "Adobe"]
}
}
}

or:

return client.search {
indices ""test"
types "type1"
source {{
query {
text {
["software.name (http://software.name)": "Adobe"]
}
}}
}
}

to name but two options I've tried. They all fail with:

SearchParseException[[test][4]: from[-1],size[-1]: Parse Failure [No
parser for element [text]]]; }

So Shay, any idea how to fulfill your suggestion in Groovy? :frowning: This
is as much for me to understand how to do things in Groovy as it is to
solve this particular example.

On Jun 12, 9:22 am, Shay Banon <shay.ba...@elasticsearch.com (http://elasticsearch.com)> wrote:

The query itself can look like: { "text" : { "software.name (http://software.name)" : "adobe" } }

On Friday, June 10, 2011 at 8:08 PM, Jondow wrote:

Ok, so I figured out part of the problem. It was actually a red
herring, related to the use of the 'field' keyword keywork within a
Grails controller context. That part is now sorted having moved the
search to a Grails service, but I'm still not able to target nested
information. In this case my JSON is structured as follows:

{
name1 = value1
name2 = value2
software = [{'name':'Adobe Reader', 'version': '1.0'},
{'name':'Mozilla Firefox', 'version':'4.0'}]
}

How would I target searching for software with the name 'adobe'? What
would the JSON look like for that?


(Jondow) #9

Right, that'll be the problem then. I'm limited to 0.16.0 right now
because you upgraded 0.16.1 (or was it in .2) to Groovy 1.8. I'm using
this within Grails 1.3.7 which isn't at 1.8 yet and I can't upgrade to
Grails 1.4 (which isn't actually released yet anyway) just yet due to
some unrelated issues it causes with my current app. No matter, I've
reverted to just crafting straight JSON as a String and handing that
to the search as its source, and that works better for me, as the
documentation examples are all in JSON format so I don't have to
fiddle around as much to get to the compatible Groovy builder syntax.
It's fine. It's working for me for now. Thanks for your responses
Shay. ES is an excellent framework and you can be very proud of your
handiwork, and those that assist you.

On Jun 14, 11:09 am, Shay Banon shay.ba...@elasticsearch.com wrote:

Which elasticsearch version are you using? text query was added in 0.16.1.On Monday, June 13, 2011 at 3:56 PM, Jondow wrote:

I still can't get this to work in Groovy. I've tried every possible
permutation of the syntax to match Shay's response, but all to no
avail. So for instance:

return client.search {
indices "test"
types "type1"
source {
text = {
["software.name (http://software.name)": "Adobe"]
}
}
}

or:

return client.search {
indices ""test"
types "type1"
source {{
query {
text {
["software.name (http://software.name)": "Adobe"]
}
}}
}
}

to name but two options I've tried. They all fail with:

SearchParseException[[test][4]: from[-1],size[-1]: Parse Failure [No
parser for element [text]]]; }

So Shay, any idea how to fulfill your suggestion in Groovy? :frowning: This
is as much for me to understand how to do things in Groovy as it is to
solve this particular example.

On Jun 12, 9:22 am, Shay Banon <shay.ba...@elasticsearch.com (http://elasticsearch.com)> wrote:

The query itself can look like: { "text" : { "software.name (http://software.name)" : "adobe" } }

On Friday, June 10, 2011 at 8:08 PM, Jondow wrote:

Ok, so I figured out part of the problem. It was actually a red
herring, related to the use of the 'field' keyword keywork within a
Grails controller context. That part is now sorted having moved the
search to a Grails service, but I'm still not able to target nested
information. In this case my JSON is structured as follows:

{
name1 = value1
name2 = value2
software = [{'name':'Adobe Reader', 'version': '1.0'},
{'name':'Mozilla Firefox', 'version':'4.0'}]
}

How would I target searching for software with the name 'adobe'? What
would the JSON look like for that?


(Shay Banon) #10

Using 0.16.2 with groovy 1.7 should work well, did not use any 1.8 features (and if so, no problem fixing it in the 0.16 branch).

On Wednesday, June 15, 2011 at 12:18 AM, Jondow wrote:

Right, that'll be the problem then. I'm limited to 0.16.0 right now
because you upgraded 0.16.1 (or was it in .2) to Groovy 1.8. I'm using
this within Grails 1.3.7 which isn't at 1.8 yet and I can't upgrade to
Grails 1.4 (which isn't actually released yet anyway) just yet due to
some unrelated issues it causes with my current app. No matter, I've
reverted to just crafting straight JSON as a String and handing that
to the search as its source, and that works better for me, as the
documentation examples are all in JSON format so I don't have to
fiddle around as much to get to the compatible Groovy builder syntax.
It's fine. It's working for me for now. Thanks for your responses
Shay. ES is an excellent framework and you can be very proud of your
handiwork, and those that assist you.

On Jun 14, 11:09 am, Shay Banon <shay.ba...@elasticsearch.com (http://elasticsearch.com)> wrote:

Which elasticsearch version are you using? text query was added in 0.16.1.On Monday, June 13, 2011 at 3:56 PM, Jondow wrote:

I still can't get this to work in Groovy. I've tried every possible
permutation of the syntax to match Shay's response, but all to no
avail. So for instance:

return client.search {
indices "test"
types "type1"
source {
text = {
["software.name (http://software.name)": "Adobe"]
}
}
}

or:

return client.search {
indices ""test"
types "type1"
source {{
query {
text {
["software.name (http://software.name)": "Adobe"]
}
}}
}
}

to name but two options I've tried. They all fail with:

SearchParseException[[test][4]: from[-1],size[-1]: Parse Failure [No
parser for element [text]]]; }

So Shay, any idea how to fulfill your suggestion in Groovy? :frowning: This
is as much for me to understand how to do things in Groovy as it is to
solve this particular example.

On Jun 12, 9:22 am, Shay Banon <shay.ba...@elasticsearch.com (http://elasticsearch.com)> wrote:

The query itself can look like: { "text" : { "software.name (http://software.name)" : "adobe" } }

On Friday, June 10, 2011 at 8:08 PM, Jondow wrote:

Ok, so I figured out part of the problem. It was actually a red
herring, related to the use of the 'field' keyword keywork within a
Grails controller context. That part is now sorted having moved the
search to a Grails service, but I'm still not able to target nested
information. In this case my JSON is structured as follows:

{
name1 = value1
name2 = value2
software = [{'name':'Adobe Reader', 'version': '1.0'},
{'name':'Mozilla Firefox', 'version':'4.0'}]
}

How would I target searching for software with the name 'adobe'? What
would the JSON look like for that?


(system) #11