如何使用 PostgreSQL 在 Rails 7 中高效处理大型 JSONB 数据

问题描述 投票:0回答:1

我目前正在开发一个 Rails 7 应用程序,该应用程序大量利用 PostgreSQL 的

JSONB
数据类型来存储大量非结构化数据。当我寻求优化读写操作时,我特别有兴趣了解索引和查询这些字段的最佳实践。这是我当前如何处理
JSONB
数据的简单示例:

class User < ApplicationRecord
  # Users table has a JSONB column named :properties
end

# Querying JSONB data
User.where("properties @> ?", {notifications: true}.to_json)

所以:

  1. 在 Rails 7 中对
    JSONB
    列建立索引以提高性能的最佳实践是什么?
  2. 是否有人在
    ActiveRecord
    中实现了自定义范围或方法 充分利用 PostgreSQL 的
    JSONB
    功能来获得更多 复杂的查询?
  3. Rails 7 中关于数据操作的
    JSONB
    是否与以前的版本有显着不同?

我正在寻找可以提高性能的见解或优化,尤其是对于复杂的查询。任何建议或代码片段将不胜感激!

ruby-on-rails postgresql jsonb
1个回答
0
投票

索引

gin
列上使用
jsonb
索引可有效搜索 jsonb 文档中出现的键或键/值对。

CREATE INDEX idx_properties ON users USING GIN (properties);

或者作为 Rails 迁移

class AddIndexToUsers < ActiveRecord::Migration
  def change
    add_index :users, :properties, using: :gin
  end
end

如果您想要与特定键对应的值的特定索引,也可以创建表达式索引。

CREATE INDEX idx_properties ON users ((properties->>'notifications'));

或者作为 Rails 迁移

class AddIndexToUsers < ActiveRecord::Migration
  def change
    add_index :users, "(properties->>'notifications')"
  end
end

复杂查询的范围和函数

即使它处于维护模式,我也使用 jsonb_accessor gem 取得了很多成功。它支持:

将 jsonb 支持的字段作为 ActiveRecord 模型的一等公民输入

它还添加了用于查询 jsonb 列的通用范围。

gem 做了很多事情,因此请查看 README 以获取支持功能的完整详细说明,但这里是一个开箱即用的一些常见功能的简单示例。

class User < ApplicationRecord
  # notifications and email now behave similar to normal attributes
  jsonb_accessor :properties, notifications: :boolean, email: :string
  validates :notifications, presence: true
  validates :email, presence: true, uniqueness: true

  scope :with_notifications, -> { properties_where(notifications: true) }
  
  def notifications_enabled?
    notifications == true
  end
end

User.jsonb_where(:properties, notifications: true)
User.jsonb_where_not(:properties, notifications: true)
# or alternatively
User.properties_where(notifications: true)
User.properties_where_not(notifications: true)
© www.soinside.com 2019 - 2024. All rights reserved.