0

Related: How to do this in MongoDB db.foo.find() syntax.

Let's suppose I have a model

class Foo(Document):
    name = StringField()

And the database state for the collection is:

[{"name":"Jesús"},{"name":"Jesus"}]

I want a query that match both documents, i.e. search, but with diacritics normalized, something like:

Foo.objects.filter(name__icontains="jesus")

Is there a way to do this directly in mongoengine?

Nicolas Martinez
  • 719
  • 1
  • 6
  • 23

1 Answers1

0

With python, you can import unidecode, and then compare all accents to normal text as,

from unidecode import unidecode
li = [ ]
for entry in Foo.objects:
    if unidecode(entry.name) == "Jesus":
        li.append(entry)

# now li has your filtered entries

Alternatively, you can do

from unidecode import unidecode
li = [ entry for entry in Foo.objects if unidecode(entry.name) == "Jesus" ]

Note: You have to install unidecode using pip install unidecode.

EDIT: The following code works as expected,

>>> unidecode('Jesús')
Jesus
vrintle
  • 5,501
  • 2
  • 16
  • 46
  • That's ok, I know about `unidecode` lib... but using your first snippet yields `SyntaxError: keyword can't be an expression` – Nicolas Martinez Apr 16 '20 at 19:50
  • @NicolasMartinez: I'm sorry, I thought it is valid to place functions inside `.filter` method. But, I was totally wrong. I've now edited my answer. I don't think that you can do it with `.filter` method anymore. No? – vrintle Apr 17 '20 at 02:53
  • No, and this method is extremely less performant, at least in my typical data – Nicolas Martinez Apr 22 '20 at 13:00
  • I don't know about your data, but I think my method should be performant atleast, as per [this article](http://docs.mongoengine.org/tutorial.html#accessing-our-data). However, I will try to improve myself, if you'll explain me more about your data. – vrintle Apr 22 '20 at 13:47