české hledání v JSONFieldu

33 views
Skip to first unread message

Vláďa Macek

unread,
Dec 6, 2017, 8:25:25 AM12/6/17
to djan...@googlegroups.com
Zdar,

postgres i Django umožňuje fajnově unaccented case insensitive hledání v
normálních fieldech. Tj. name__unaccent__icontains

Zprovoznil jste někdo efektivní hledání stejného typu v klíčích nativního
JSONFieldu v novém Djangu? Ideálně trochu čistě bez raw SQL, ale přežil
bych to.

Díky. :-)

Vláďa

Honza Král

unread,
Dec 6, 2017, 10:05:12 AM12/6/17
to djan...@googlegroups.com
Ahoj,

hledani pomoci __unaccent__icontains nebude nikdy efektivni z definice
- vzdy se bude jednat o full scan na tech datech.

Muzu se zeptat, na co takovy lookup potrebujes? Hodne silne mi to
zavani nestastnym navrhem kde mas data v klicich misto hodnotach...


Honza Král
E-Mail: honza...@gmail.com
Phone: +420 606 678585
> --
> --
> E-mailová skupina djan...@googlegroups.com
> Správa: http://groups.google.cz/group/django-cs
> ---
> Tuto zprávu jste obdrželi, protože jste přihlášeni k odběru skupiny django-cs ve Skupinách Google.
> Chcete-li zrušit odběr skupiny a přestat dostávat e-maily ze skupiny, zašlete e-mail na adresu django-cs+...@googlegroups.com.
> Chcete-li zobrazit tuto diskusi na webu, navštivte https://groups.google.com/d/msgid/django-cs/580ec7d2-658b-efdc-f3b8-f64651333279%40sandbox.cz.
> Další možnosti najdete na adrese https://groups.google.com/d/optout.

Vláďa Macek

unread,
Dec 6, 2017, 12:20:42 PM12/6/17
to djan...@googlegroups.com
Čau Honzo,

díky.

Nevylučuju nedostatečný návrh a rád se inspiruju. ;-)

Cílem je jednoduše case-insensitive accent-insensitive substring search na
hodnotě uvnitř JSONu v pg.

Tohle máme v modelu

    fc_data = JSONField(blank=True, editable=False, default=dict)

a jméno osoby dostáváme v Python takhle:

    fc_data['contactInfo']['fullName']

Takže jméno je zanořený v JSONu. Jména se nemění často a určitě by se dala
vytáhnout do formy podobnější vyhledávacímu stroji/lépe indexované tabuli.
Napadlo nás, zda by cestou nejmenšího odporu nebylo využití toho, že to je
pg typ `jsonb` a Django má už snad umět do JSONu koukat. Zatím jsem
nestudoval a je to vcelku specifický případ, tak sonduju, jestli už někdo
nevyřešil, případně jak či jakým směrem.

psycopg2~=2.7.0
django~=1.11.0

Díky,

Vláďa

starenka .

unread,
Dec 6, 2017, 12:55:31 PM12/6/17
to djan...@googlegroups.com
afaik se da i na nested fieldu udelat index (nezkousel sem, negugloval sem, mazu se ahoj)

-----
'aknerats'[::-1]

--
--
E-mailová skupina djan...@googlegroups.com
Správa: http://groups.google.cz/group/django-cs
---
Tuto zprávu jste obdrželi, protože jste přihlášeni k odběru skupiny django-cs ve Skupinách Google.
Chcete-li zrušit odběr skupiny a přestat dostávat e-maily ze skupiny, zašlete e-mail na adresu django-cs+unsubscribe@googlegroups.com.
Chcete-li zobrazit tuto diskusi na webu, navštivte https://groups.google.com/d/msgid/django-cs/65f9b392-5ec3-a564-6618-e8db788e8a07%40sandbox.cz.

Honza Král

unread,
Dec 6, 2017, 1:07:01 PM12/6/17
to djan...@googlegroups.com


On Dec 6, 2017 18:55, "starenka ." <star...@gmail.com> wrote:
afaik se da i na nested fieldu udelat index (nezkousel sem, negugloval sem, mazu se ahoj)

Index (mimo inverted tsearch) nepomuze na icontains.


-----
'aknerats'[::-1]

On Dec 6, 2017 18:20, "Vláďa Macek" <ma...@sandbox.cz> wrote:
Čau Honzo,

díky.

Nevylučuju nedostatečný návrh a rád se inspiruju. ;-)

Cílem je jednoduše case-insensitive accent-insensitive substring search na
hodnotě uvnitř JSONu v pg.

Tohle máme v modelu

    fc_data = JSONField(blank=True, editable=False, default=dict)

a jméno osoby dostáváme v Python takhle:

    fc_data['contactInfo']['fullName']

Aha, tak to jsem ti krivdil. Pochopil jsem, ze chces hledat nejakou cast klice, ne hodnoty ulozene pod klicem. Proto me poznamky o mozna spatnem designu...

Takže jméno je zanořený v JSONu. Jména se nemění často a určitě by se dala
vytáhnout do formy podobnější vyhledávacímu stroji/lépe indexované tabuli.
Napadlo nás, zda by cestou nejmenšího odporu nebylo využití toho, že to je
pg typ `jsonb` a Django má už snad umět do JSONu koukat. Zatím jsem
nestudoval a je to vcelku specifický případ, tak sonduju, jestli už někdo
nevyřešil, případně jak či jakým směrem.

Django, via postgres, so jsonu umi koukat, ale icontains nevim nevim. Kazdopadne tohle vypada spis jako ukol pro search, at uz t-search v postgresu a/nebo externi nastroj ala elasticsearch. Jinak to efektivni nebude.

V soucasne dobe je imho jedina moznost pres funkce v postgresu, tedy nejaky raw sql ala unaccent(json_string(fc_data, 'contactInfo.fullName')) ILIKE unaccent('%blabla%')

Ale opet opakuji, tohle efektivni z definice nikdy nebude (jak ma vykon tak na kvalitu), doporucuju se podivat na https://docs.djangoproject.com/en/1.11/ref/contrib/postgres/search/
A/nebo samozrejme komplexni (a komplikovanejsi na deploy) reseni pres elasticsearch. 

Vláďa Macek

unread,
Dec 6, 2017, 1:08:41 PM12/6/17
to djan...@googlegroups.com
On 6.12.2017 19:06, Honza Král wrote:
>
>
> On Dec 6, 2017 18:55, "starenka ." <star...@gmail.com
> <mailto:star...@gmail.com>> wrote:
>
> afaik se da i na nested fieldu udelat index (nezkousel sem,
> negugloval sem, mazu se ahoj)
>
>
> Index (mimo inverted tsearch) nepomuze na icontains.

Yes, myslím, že po stačil match na začátky slov. Aby kdyby uživatel zadal
"cerny", tak aby to našlo "Marek Černý" i "Černý pes".

V.

Reply all
Reply to author
Forward
0 new messages