Apply multiple filters on nested array of properties


(Christopher Coté) #1

I'm having an issue using multiple filters on an array of nested filters.

My document looks something like this.

{
"name":"Python Test"
"filters" : [
{
"name" : "duration",
"value" : "2161"
},
{
"name" : "media",
"value" : "video"
},
{
"name" : "content-type",
"value" : "screencast"
},
{
"name" : "timing",
"value" : "anytime"
},
{
"name" : "price",
"value" : 0
}
],
}

my mapping is along these lines.

"filters" : {
"type" : "nested",
"properties" : {
"name" : {
"type" : "string",
"index" : "not_analyzed",
"omit_norms" : true,
"index_options" : "docs"
},
"value" : {
"type" : "string",
"index" : "not_analyzed",
"omit_norms" : true,
"index_options" : "docs"
}
}
},

I'm trying to apply multiple filters to the search eg; only return
documents that have content-type: screencast and timing: anytime also
need to be able to apply a search term.

my current query looks something like this, about the 100th iteration.

{
"fields":cls.Search._fields,
"from":frm,
"size":size,
"query":{
"filtered":{
"query":{
"query_string": {
"query": search_term,
"fields": cls.Search._search_fields,
}
},
"filter":{
"nested":{
"path":"filters",
"query":{
"match_all" : {}
},
"filter":{
"and":[
{"and":[

{"term":{"filters.name":"content-type"}},
{"term":{"filters.value":"lecture"}}
]},
{"and":[
{"term":{"filters.name":"price"}},

{"range":{"filters.value":{"from":0, "to":9999}}}
]}
]
}
}
}
}
}
}

I'm able to use a bool query in the nested filter, almost exactly like the
example
here. http://www.elasticsearch.org/guide/reference/query-dsl/nested-filter/

and if I hard code multiple "must" keys I can get it to work with multiple
filters, however Python (my language of choice) doesn't allow for multiple
"must" keywords in a dictionary, so I'm not able to dynamically create the
query, which is a must. I would also like to avoid raw string formatting if
possible.

I feel like this document schema is pretty common, but I haven't found any
examples of applying multiple filters on an array of nested objects.

I'm not totally against changing the schema, but again, I feel like this
would be a pretty common approach.

Ideas or solutions?

--
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.
For more options, visit https://groups.google.com/groups/opt_out.


(Christopher Coté) #2

I was able to get something working.

The secret was using "AND"ing multiple nested filters...

My final query looks like this.

After reading this post several times, I figured out his
solution. https://groups.google.com/forum/#!searchin/elasticsearch/multiple$20filters$20nested/elasticsearch/woVLXF_pnM8/gOoqhg-9GT8J

q = {
"fields":cls.Search._fields,
"from":frm,
"size":size,
"query":{
"query_string": {
"query": search_term,
"fields": cls.Search._search_fields,
}
},
"filter":{
"and":[
{"nested": {
"path": "filters",
"query":{
"filtered": {
"query": { "match_all": {}},
"filter": {
"and": [
{"term": {"filters.name":
"content-type"}},
{"term": {"filters.value":
"screencast"}}
],
}
}
}
}},
{"nested": {
"path": "filters",
"query":{
"filtered": {
"query": { "match_all": {}},
"filter": {
"and": [
{"term": {"filters.name": "price"}},
{"range": {"filters.value":
{"from":0, "to":99999}}}
],
}
}
}
}}
]
},
}

--
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.
For more options, visit https://groups.google.com/groups/opt_out.


(system) #3