4

I am using elasticsearch-dsl-py and would like to filter on a term that is contained inside another one like this:

"slug": {
    "foo": "foo-slug",
    "bar": "bar-slug "
}

What I do is this :

search.query(‘filtered’, filter={"term": {"slug.foo": "foo-slug"}})

I would prefer something like

search.filter(term, slug.foo="foo-slug")

But I can’t as keyword can’t include dots.

1
  • I am not a Python expert by any stretch, but can't you use the dictionary syntax from the query? As in search.filter(term, {'slug.foo':'foo-slug'})? Commented Nov 20, 2014 at 0:46

5 Answers 5

11

If it helps anyone else, I had the same problem creating this kind of query against a child property not using nested objects. I found the solution was to use the query method instead of the filter method:

search.query('match', **{"slug.foo": "foo-slug"})

This worked for me in ElasticSearch 1.5.2.

Sign up to request clarification or add additional context in comments.

Comments

8

edit... DON'T DO THIS: See aaronfay's answer for the correct approach.

This doesn't seem to be documented anywhere which is sad...

>>> search.filter('term', slug__foo='foo-slug').to_dict()
{'query': {'filtered': {'filter': {'term': {u'slug.foo': 'foo-slug'}}, 'query': {'match_all': {}}}}}

The double underscore will be converted into dot notation. No idea if this is stable.

2 Comments

ohhhhh my god THX ! The documentation is sad indeed.
arronfay's answer is the correct approach and the double underscore probably shouldn't be used as it could break in future releases.
0

So I am assuming that slug is a nested object in a larger document. In the current version (0.0.8) this can be achieved like so:

from elasticsearch_dsl import F

...

f = F('term', foo='foo-slug')
search = search.filter('nested', path='slug', filter=f)

Comments

0

It's a long time after the question had been asked, but just in case anyone comes across this post, Charles's answer is actually correct, (The method shouldn't break since it's actually mentioned in the packages docs now).

As the docs mention:

...,the Q shortcut (as well as the query, filter, and exclude methods on Search class) allows you to use __ (double underscore) in place of a dot in a keyword argument:

s = Search()
s = s.filter('term', category__keyword='Python')
s = s.query('match', address__city='prague')

It also mentions aaronfay's answer:

Alternatively you can always fall back to python’s kwarg unpacking if you prefer:

s = Search()
s = s.filter('term', **{'category.keyword': 'Python'})
s = s.query('match', **{'address.city': 'prague'})

Comments

-2

This will do the trick for you:

args = {
    "slug.foo": "foo-slug"
}
search.filter(term, **args)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.