2016-02-20 2 views
0

Возможно ли выполнить поиск по одному ключевому значению в списке словарей с использованием оператора ILIKE (icontains)? Мое поле JSON выглядит следующим образом:Django JSONField и поиск по списку словарей с использованием ILIKE

object = MyModel() 
object.json_data = [ 
    { 
     "type": 1, 
     "results": [ 
      { 
       "score": 1, 
       "comment": "Some text comment 1", 
      }, 
      { 
       "score": 2, 
       "comment": "Some text comment 2", 
      }, 
      { 
       "score": 3, 
       "comment": "Some text comment 3", 
      } 
     ] 
    }, 
    { 
     "type": 2, 
     "results": [ 
      { 
       "score": 4, 
       "comment": "Some text comment 4", 
      }, 
      { 
       "score": 5, 
       "comment": "Some text comment 5", 
      }, 
      { 
       "score": 6, 
       "comment": "Some text comment 6", 
      } 
     ] 
    } 
] 
object.save() 

А теперь, как написать запрос для поиска в ключе «комментарий»?

MyModel.objects.filter(json_data__??__results__??__comment__icontains="text comment") 

Я использую Django 1.9.

Спасибо!

+0

Вам нужно будет написать свою собственную функцию фильтра для фильтрации результатов с регулярным выражением. Каков точный результат, который вам нужен? QuerySet? список матчей? –

ответ

6

Вы должны быть в состоянии найти просто приковав его, Джанго стиль:

MyModel.objects.filter(json_data__results__contains={"comment":"text comment"}) 

выписка документации для поля JSON в Django 1.9: https://docs.djangoproject.com/es/1.9/ref/contrib/postgres/fields/#querying-jsonfield

, который включает в себя contains поиск: https://docs.djangoproject.com/es/1.9/ref/contrib/postgres/fields/#std:fieldlookup-hstorefield.contains

Если это не работает для без учета регистра, то я увижу, какой запрос он производит, и просто переработает его с дополнительным, где:

MyModel.objects.extra(where=["json_data->>'results'->'comment' ILIKE %s"], params=["%text comment%"]) 

или вы можете использовать специальные символы для JSON, как указано в Postgres документации, как <@

http://www.postgresql.org/docs/9.5/static/functions-json.html

+1

Дело в том, что я не могу фильтровать все элементы в списке. Когда я указываю index = "json_data__0__results__0__comment__contains = 'Text", все работает, но как фильтровать все элементы в списке? – User

+1

Это кажется действительно странным, оно обязательно должно переходить все значения списка. Здесь автор демонстрирует, что это работает для него ... http://orokusaki.posthaven.com/djangos-new-jsonfield-is-awesome Если что-то вроде 'comment__contains = 'text'' не работает для вас, тогда Я предлагаю использовать таможню, где, как я писал в своем ответе. Или писать полностью raw sql. –

+0

Нет. Работы: 'Выбрать * из xxx WHERE json_data :: jsonb-> 0 -> 'results' -> 0 -> 'comment' = '" Текст "';' ***** Не работает: 'Выбрать * from xxx WHERE json_data :: jsonb -> 'results' -> 'comment' = '"Text"'; '***** Works:' Выбрать * из xxx WHERE json_data :: jsonb #> ARRAY ['0 ',' results ',' 0 ',' comment '] =' "Text" '; '***** Не работает:' Выберите * из xxx WHERE json_data :: jsonb #> ARRAY [' results ', 'comment'] = '"Text"'; '***** Не работает:' Выберите * из xxx WHERE json_data :: jsonb @> '{"comment": "Text"}' :: jsonb; ' ***** Так что я должен каждый раз указывать индекс списка :-( – User

1

это работает для меня (обратите внимание на [])

запроса = User .objects.filter (data__campaigns__contains = [{'key': 'value'}])