Postgres:按带注释/串联的json值搜索

时间:2019-05-17 07:52:15

标签: django postgresql django-models

我有一个使用postgres json列的Django模型。

class ClassName:
    json=JsonField()

这是json字段中的架构。

{
  'lev1': {
    'lev2': {
      first_name: 'Alex',
      last_name: 'Anderson',
      street: '242 Bell St,',
      city:'New York',
      state:'NY',
    }
}

现在我有了这些数据,我必须使用用户的全名和完整地址对其进行过滤。

我正在寻找

ClassName.objects.annotate(
    full_name=Concat(F('lvl1__lvl2__first_name'), Value(' '),
                    F('lvl1__lvl2__last_name')),
    full_address=Concat(F('lvl1__lvl2__address'), Value(' '),
                        F('lvl1__lvl2__city'), Value(' '),
                        F('lvl1__lvl2__state'), Value(' '),
                        F('lvl1__lvl2__zipcode')),
).filter(full_name__icontains="Alex Anderson")

我尝试了所有不同的json函数,但无法获得正确的组合。

1 个答案:

答案 0 :(得分:1)

不幸的是,Django中有一个issue阻止直接在F函数中使用JSON字段...这使您的代码无法正常工作...

解决方案是在代码中嵌入原始SQL片段。丑陋,但这就是我们所拥有的。

TestJsonAnn.objects.annotate(
    full_name=Concat(
        RawSQL("(json->'lev1'->'lev2'->>'first_name')", ()),
        Value(' '),
        RawSQL("(json->'lev1'->'lev2'->>'last_name')", ())
    )
).filter(full_name__icontains="Alex Anderson")

通知->>运算符在最后一次提取时使用,而不是->。这是必需的,因为->将以JSON对象的形式返回数据,因此您的字符串将另外加引号,->>将其作为字符串返回。有关在原始SQL中提取字段的更多信息,请参见PostgreSQL docs