【问题标题】:Postgres compare multiple jsonb fieldsPostgres比较多个jsonb字段
【发布时间】:2016-05-05 18:52:37
【问题描述】:

我在一个表中有一个 jsonb“联系人”字段:

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

例子:

  {
  "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}'

【问题讨论】:

    标签: postgresql jsonb


    【解决方案1】:

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

    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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-25
      • 1970-01-01
      • 2021-02-24
      • 1970-01-01
      • 2011-10-30
      相关资源
      最近更新 更多