2016-07-25 89 views
3

我想了解一種方法來查詢我的模型的特定實例上的postgres JSONField中的數據。查詢Django模型的JSONField的內容

從我所看到的情況來看,所有的用例都是相同的,如果你有一個屬性JSONField,然後選擇你的模型的所有實例,其中屬性 - >> color ='red'或其他。

讓我們給這個更真實的例子,假設我們有一個模型Shoe,它有價格和數量,無論作爲字段,但隨後也JSONField稱爲versions,這是對象的數組,具有每個對象讓每個版本都特別的東西。

因此,如果鞋模型的一個實例是飛人喬丹,屬性JSONField可能看起來像:

[ 
    { 
     color: black, 
     edition: limited, 
     tongueColor: red 
    }, 
    { 
     color: black, 
     edition: standard 
    }, 
    { 
     color: gold, 
     edition: fancy, 
     bright: very 
    } 
] 

因此,有兩件事情可以做,我們可以:

  1. 查詢模型對於所有有可用版本的鞋子,其顏色:黑色(將返回我們的Air Jordans,加上其他鞋子)或
  2. 查詢JSONField版本內所有對象的模型實例,其中color = black。所以如果我們已經有Shoe.objects.filter(name='Air Jordans')什麼的,可以在最後加上一些方法或東西來返回上面的前兩個對象color == black

我可以在網上找到第一個例子,但不是第二個例子。

我可以把對象放入內存並從那裏過濾,但是這個JSONField是我希望存儲大量任意數據的地方,所以能夠在不將整個blob存入內存的情況下進行查詢是相當重要的。 JSONField可以支持嗎?

+0

你怎麼知道我們可以做第二件事? – valignatev

+1

我不太確定,但我認爲你可以這樣做:'.filter(versions__contains = {'color':'black'})'或'.filter(versions__contains = [{'color':'black'}} ])'。否則,你應該創建一些自定義查找並使用'json_to_recordset()'https://www.postgresql.org/docs/9.5/static/functions-json.html#FUNCTIONS-JSON-PROCESSING-TABLE –

+0

@valentjedi - 我有不知道這是否可能,但很可能不是。 – cbrainerd

回答

1

@AntoinePinsard我指出了正確的方向 - json_to_recordset()。

我目前使用的是這樣的:

SELECT * FROM (
    SELECT j.* from shoes, json_to_recordset(json_field_name) as 
    j(color text, edition text, tongueColor: text, bright text) where 
    shoes.shoe_name = 'Air Jordan' 
) subset 
WHERE subset.color= "black" 

所以內部的select語句將在內部建立一個記錄,看起來像這樣:

 
color | edition | tongueColor | bright 
------+----------+-------------+-------- 
black | limited | red   | 
black | standard |    | 
gold | fancy |    | very 

,然後外語句查詢該內部記錄集(在這種情況下,其中color ='black'並且將返回:

 
color | edition | tongueColor | bright 
------+----------+-------------+-------- 
black | limited | red   | 
black | standard |    | 

感謝大家的幫助!

+0

您是否可以將此解決方案應用到Django ORM中? – skulk001

1

這可能會爲你工作:

Shoes.objects.filter(yourJsonFieldName__contains={'colors': 'black'})