如何查询jsonb?

时间:2016-06-01 12:57:36

标签: phoenix-framework ecto

我将设置存储到配置字段中:

  schema "teams" do
    field :owner_id, :integer
    field :is_base_team, :boolean
    field :config, :map
    has_many :team_users, {"team_user", App.TeamUser}
  end

因此,我需要在see_owner中构建读取参数config的查询:

teams_users =
    from(t in Team, where: t.owner_id == ^user_id and fragment("?->>'see_owner' == ?", t.config, true))
    |> Repo.all()
    |> Repo.preload(:team_users)

然而,我收到了错误:

** (Postgrex.Error) ERROR (undefined_function): operator does not exist: text == boolean
        (ecto) lib/ecto/adapters/sql.ex:395: Ecto.Adapters.SQL.execute_and_cache/7
        (ecto) lib/ecto/repo/queryable.ex:127: Ecto.Repo.Queryable.execute/5
        (ecto) lib/ecto/repo/queryable.ex:40: Ecto.Repo.Queryable.all/4
        (app) web/channels/user_socket.ex:67: App.UserSocket.get_team_users_ids/1
        (app) web/channels/user_socket.ex:40: App.UserSocket.connect/2
        (phoenix) lib/phoenix/socket/transport.ex:167: Phoenix.Socket.Transport.connect_vsn/6
        (phoenix) lib/phoenix/transports/websocket.ex:73: Phoenix.Transports.WebSocket.init/2
        (phoenix) lib/phoenix/endpoint/cowboy_websocket.ex:12: Phoenix.Endpoint.CowboyWebSocket.init/3
        (cowboy) src/cowboy_handler.erl:64: :cowboy_handler.handler_init/4
        (cowboy) src/cowboy_protocol.erl:442: :cowboy_protocol.execute/4

那么,我如何在查询中添加config.see_owner config jsonb see_owner booleanecto 2.0.0-rc.5属性?

我正在使用from(t in Team, where: t.owner_id == ^user_id and fragment("?->> 'see_owner' = '?'", t.config, true))

修改

我已将postgres查询修复为:

SELECT t0."id", t0."owner_id", t0."is_base_team", t0."config" FROM "teams" AS t0 WHERE ((t0."owner_id" = $1) AND t0."config"->> 'see_owner' = 'TRUE') [3]

在日志I中,它被翻译为:

sql> SELECT t0."id", t0."owner_id", t0."is_base_team", t0."config" FROM "teams" AS t0 WHERE ((t0."owner_id" = $1) AND t0."config"->> 'see_owner' = 'TRUE') [3]
[2016-06-01 17:43:33] [42804] ERROR: cannot subscript type boolean because it is not an array

但是结果是空的,但团队,配置等于{" see_owner":true}

EDIT2

使用owner_id检查,我收到错误:

SELECT t0."id", t0."owner_id", t0."is_base_team", t0."config" FROM "teams" AS t0 WHERE (t0."config"->> 'see_owner' = 'TRUE')
[2016-06-01 17:44:09] 0 rows retrieved in 9ms (execution: 4ms, fetching: 5ms)

我删除了owner_id检查,但结果是空的:

'see_owner' = 'TRUE'

我删除了owner_id支票,并使用'see_owner' = 'true'的小写字母作为sql> SELECT t0."id", t0."owner_id", t0."is_base_team", t0."config" FROM "teams" AS t0 WHERE (t0."config"->> 'see_owner' = 'true') [2016-06-01 17:46:40] 16 rows retrieved starting from 1 in 7ms (execution: 3ms, fetching: 4ms) ,我得到的结果没有错误:

TRUE

所以,我认为Ecto需要将boolean类型转换为postrgres本机查询,而不是像现在这样将FALSE或{{1}}转换为大写字母。

另外,我不知道为什么带有owner_id的本机查询出错,因为我从日志中复制了生成的本机查询,它应该正常工作..

1 个答案:

答案 0 :(得分:0)

这里的问题是你的条件,==在PostgreSQL中无效。

试试这个:

from(t in Team, where: t.owner_id == ^user_id and fragment("?->>'see_owner' = ?", t.config, true))