Using NOT in a nested filter


(Nathan-2) #1

I am having trouble with a filter. I have items in my index, with nested
"ratings"

curl -XPOST "http://localhost:9200/nestedfilters/item/_mapping" -d '
{
"item" : {
"properties" : {
"description" : {
"type" : "string"
},
"ratings" : {
"type" : "nested",
"properties" : {
"rater_username" : {
"type" : "string",
"index" : "not_analyzed"
},
"rating" : {
"type" : "integer",
"index" : "not_analyzed"
}
}
}
}
}
}
'

I want to be able to find items where a certain user has not rated the
item. I have tried using NOT, but it finds anything rated by anybody else,
regardless of whether the specific user has rated it. I can't seem to
figure out how to use a MISSING filter either. Here is what I have tried:

curl -XPOST "http://localhost:9200/nestedfilters/item/_search?pretty=true"
-d '
{
"query" : {
"match_all" : {}
},
"filter" : {
"nested" : {
"path" : "ratings",
"filter" : {
"not" : {
"term" : {
"ratings.rater_username" : "user1"
}
}
}
}
}
}
'

and

curl -XPOST "http://localhost:9200/nestedfilters/item/_search?pretty=true"
-d '
{
"query" : {
"match_all" : {}
},
"filter" : {
"nested" : {
"path" : "ratings",
"filter" : {
"and" : [{
"term" : {
"ratings.rater_username" : "user1"
}
},{
"missing" : {
"field" : "ratings.rating"
}
}]
}
}
}
}
'

Here is the gist with a full example:
https://gist.github.com/nathanmoon/8339950.

Is there another way I haven't thought of to craft a filter like this? Or
do I need to index my data differently to support this type of filtering?
Thanks for any help!

Nathan

--
You received this message because you are subscribed to the Google Groups "elasticsearch" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elasticsearch+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/elasticsearch/fc6ce18d-2923-4b87-b992-fc81a72c69a4%40googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.


(Sloan Ahrens) #2

You were close. You just had the "nested" and "not" filters in the wrong order, basically.

Your (first) query says "return items that have a rating with 'ratings.rater_username' not equal to 'user1'". And so you get the first item, since it meets that requirement.

What you really want to say is "return items for which all ratings have 'ratings.rater_username' not equal to 'user1'". Here is the query you want:

curl -XPOST "http://localhost:9200/nestedfilters/item/_search" -d'
{
"query": {
"match_all": {}
},
"filter": {
"not": {
"nested": {
"path": "ratings",
"filter": {
"term": {
"ratings.rater_username": "user1"
}
}
}
}
}
}'

Here is a runnable example you can play with (you will need ES installed and running at localhost:9200, or supply another endpoint): http://sense.qbox.io/gist/289ceb80480db8b6574d5f879358e50c97aaf5da


(Nathan-2) #3

Oh right. That should have been obvious. It seems to be working great that way. Thanks!

Nathan

On Jan 9, 2014, at 1:10 PM, Sloan Ahrens sloan@stacksearch.com wrote:

You were close. You just had the "nested" and "not" filters in the wrong
order, basically.

Your (first) query says "return items that have a rating with
'ratings.rater_username' not equal to 'user1'". And so you get the first
item, since it meets that requirement.

What you really want to say is "return items for which all ratings have
'ratings.rater_username' not equal to 'user1'". Here is the query you want:

curl -XPOST "http://localhost:9200/nestedfilters/item/_search" -d'
{
"query": {
"match_all": {}
},
"filter": {
"not": {
"nested": {
"path": "ratings",
"filter": {
"term": {
"ratings.rater_username": "user1"
}
}
}
}
}
}'

Here is a runnable example you can play with (you will need ES installed and
running at localhost:9200, or supply another endpoint):
http://sense.qbox.io/gist/289ceb80480db8b6574d5f879358e50c97aaf5da


Co-Founder and CTO, StackSearch, Inc.
Hosted Elasticsearch at http://qbox.io

View this message in context: http://elasticsearch-users.115913.n3.nabble.com/Using-NOT-in-a-nested-filter-tp4047349p4047353.html
Sent from the ElasticSearch Users mailing list archive at Nabble.com.

--
You received this message because you are subscribed to a topic in the Google Groups "elasticsearch" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/elasticsearch/7yWbMCYmAFw/unsubscribe.
To unsubscribe from this group and all its topics, send an email to elasticsearch+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/elasticsearch/1389298238074-4047353.post%40n3.nabble.com.
For more options, visit https://groups.google.com/groups/opt_out.

--
You received this message because you are subscribed to the Google Groups "elasticsearch" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elasticsearch+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/elasticsearch/128FBB57-B971-4D1C-A3A6-E4F5A3F2BC3D%40gmail.com.
For more options, visit https://groups.google.com/groups/opt_out.


(system) #4