Postgres比较多个jsonb字段

时间:2016-05-05 18:52:37

标签: postgresql jsonb

我在表格中有一个jsonb“contacts”字段:

  1. 一个对象,其中每个键都是联系人类型,如邮寄,计费,紧急等。这些是松散定义的。
  2. #1中每个键的值是一个包含每种类型的一个或多个联系人的数组
  3. #2内的每个值都是包含松散定义字段的对象。
  4. 示例:

      {
      "main": [{
        "name": "Bobby Smith",
        "email": "bs@example.com", 
        "telephone": "555-999-0000"
      }, {
        "name": "Joan Smith",
        "email": "js@example.com", 
        "telephone": "555-999-0002"
      }],
      "billing": [{
        "name": null,
        "region": "Arizona",
        "address": ["PO BOX 123", "456 Nowhere Road"],
        "country": "USA",
        "locality": "BigMac",
        "postalCode": "90210"
      }],
      "emergency": [{
        "name": "John Cooper",
        "email": "jc@example.com",
        "telephone": "555-987-0000"
      }]
    }   
    

    我想有一个简单的方法来比较最外层对象中的键与名称字段以及每个数组中元素的数量。

    有效地: SELECT * FROM clients WHERE contacts#>>'{*,*,name}'='John Cooper';

    将返回包含上述内容的行,因为它匹配'{emergency,0,name}'

1 个答案:

答案 0 :(得分:2)

您需要展开当前数据库设计的数据,例如:

select t.*
from   t, jsonb_each(contacts) e, jsonb_array_elements(e.value) c
where  c ->> 'name' = 'John Cooper'

但是,这不能为您的查询使用任何索引。

更好的设计是仅在连接表中的每一行存储联系人数据,例如:

  t                  t_contact
------------------  -------------------------
 t_id primary key    t_id references t(t_id)
                     contact_type text
                     contact jsonb

然后,您可以索引t_contact(contact)并查询,例如:

select   t.*
from     t
join     t_contact using (t_id)
where    contact ->> 'name' = 'John Cooper'
group by t.t_id