how to write a query to get find value in a json f

2019-01-11 11:13发布

I have a json field in my database which is like

jsonfield = {'username':'chingo','reputation':'5'}

how can i write a query so that i can find if a user name exists. something like

username = 'chingo'
query = User.objects.get(jsonfield['username']=username)

I know the above query is a wrong but I wanted to know if there is a way to access it?

6条回答
The star\"
2楼-- · 2019-01-11 11:46

You can't do that. Use normal database fields for structured data, not JSON blobs.

If you need to search on JSON data, consider using a noSQL database like MongoDB.

查看更多
一纸荒年 Trace。
3楼-- · 2019-01-11 11:51

If you are using the django-jsonfield package, then this is simple. Say you have a model like this:

from jsonfield import JSONField
class User(models.Model):
    jsonfield = JSONField()

Then to search for records with a specific username, you can just do this:

User.objects.get(jsonfield__contains={'username':username})
查看更多
Animai°情兽
4楼-- · 2019-01-11 11:55

Here is the way I have found out that will solve your problem:

search_filter = '"username":{0}'.format(username)
query = User.objects.get(jsonfield__contains=search_filter)

Hope this helps.

查看更多
淡お忘
5楼-- · 2019-01-11 11:59

Since Django 1.9, you have been able to use PostgreSQL's native JSONField. This makes search JSON very simple. In your example, this query would work:

User.objects.get(jsonfield__username='chingo')

If you have an older version of Django, or you are using the Django JSONField library for compatibility with MySQL or something similar, you can still perform your query.

In the latter situation, jsonfield will be stored as a text field and mapped to a dict when brought into Django. In the database, your data will be stored like this

{"username":"chingo","reputation":"5"}

Therefore, you can simply search the text. Your query in this siutation would be:

User.objects.get(jsonfield__contains='"username":"chingo"')
查看更多
一纸荒年 Trace。
6楼-- · 2019-01-11 12:01

If you use PostgreSQL you can use raw sql to solve problem.

username = 'chingo'
SQL_QUERY = "SELECT true FROM you_table WHERE jsonfield::json->>'username' = '%s'"
User.objects.extra(where=[SQL_EXCLUDE % username]).get()

where you_table is name of table in your database.

Any methods when you work with JSON like with plain text - looking like very bad way. So, also I think that you need a better schema of database.

查看更多
ゆ 、 Hurt°
7楼-- · 2019-01-11 12:10

This usage is somewhat anti-pattern. Also, its implementation is not going to have regular performance, and perhaps is error-prone.
Normally don't use jsonfield when you need to look up through fields. Use the way the RDBMS provides or MongoDB(which internally operates on faster BSON), as Daniel pointed out.

Due to the deterministic of JSON format, you could achieve it by using contains (regex has issue when dealing w/ multiple '\' and even slower), I don't think it's good to use username in this way, so use name instead:

def make_cond(name, value):
    from django.utils import simplejson 
    cond = simplejson.dumps({name:value})[1:-1] # remove '{' and '}'
    return ' ' + cond # avoid '\"'

User.objects.get(jsonfield__contains=make_cond(name, value))

It works as long as

  • the jsonfield using the same dump utility (the simplejson here)
  • name and value are not too special (I don't know any egde-case so far, maybe someone could point it out)
  • your jsonfield data is not corrupt (unlikely though)

Actually I'm working on a editable jsonfield and thinking about whether to support such operations. The negative proof is as said above, it feels like some black-magic, well.

查看更多
登录 后发表回答