You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Ecto查询嵌套map中status为accepted的Event记录?是否需原生SQL?

嘿,刚好对Ecto的这类嵌套字段查询熟得很,完全不需要写原生SQL,给你几种简便的实现方式,根据你的fields字段类型来选就行:

情况1:fields是PostgreSQL的JSONB字段(最常见场景)

如果你的Event表中fields字段定义的是JSONB类型(这是Elixir/Ecto生态里存储嵌套map的常规操作),有三种直观的写法:

写法1:最简洁的Ecto 3.10+语法

从Ecto 3.10版本开始,支持直接用Map的Access语法来查询JSONB嵌套字段,代码超清爽:

from e in Event,
  where: e.fields["status"] == "accepted"

Ecto会自动把这个语法转换成对应的PostgreSQL JSONB查询语句,完全不用你操心底层细节。

写法2:用fragment配合JSONB操作符

如果你用的是旧版Ecto,或者想更明确控制SQL逻辑,可以用fragment搭配PostgreSQL的->>操作符(用来提取字符串类型的嵌套字段值):

from e in Event,
  where: fragment("?->>'status' = ?", e.fields, "accepted")

写法3:用PostgreSQL内置函数(可读性更强)

还有一种更具语义化的写法,调用PostgreSQL的jsonb_extract_path_text函数:

from e in Event,
  where: fragment("jsonb_extract_path_text(?, ?) = ?", e.fields, "status", "accepted")
情况2:fields是Ecto嵌入式Schema

如果你是用Ecto的嵌入式Schema来定义fields的结构(比如提前定义了EventFields嵌入式模型):

# 嵌入式Schema定义
defmodule EventFields do
  use Ecto.Schema
  embedded_schema do
    field :status, :string
    field :other_field, :string
  end
end

# 主Event Schema关联
defmodule Event do
  use Ecto.Schema
  schema "events" do
    field :external_id, :integer
    field :type, :string
    embeds_one :fields, EventFields
  end
end

那查询起来更直接,直接通过嵌入式字段的属性来过滤:

from e in Event,
  where: e.fields.status == "accepted"

总结一下:不管哪种情况,都不用写原生SQL,用Ecto自带的查询语法就能轻松搞定嵌套字段的过滤需求~

内容的提问来源于stack exchange,提问作者ugotchi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 09:08:09