case 语句在 select merge 中设置为模型

case statement is setting as model in select merge

这些是参数:

 %{
  "$select" => %{
    "$avg" => ["arrive_at"],
    "$count" => ["arrive_at"],
    "$fields" => ["id"],
    "$max" => ["cost"],
    "$min" => ["arrive_at"],
    "$sum" => ["arrive_at"]
  }
 }

这是代码:

 select when is_map(select) ->
        query = from(p in queryable, select: %{})

        fields =
          Enum.reduce(select, [], fn {key, value}, fields ->
            Enum.reduce(value, query, fn {k, v}, query ->
              case k do
                "$avg" ->
                  val = Enum.at(v, 0)

                  query =
                    from(
                      p in query,
                      select_merge: %{avg: avg(field(p, ^String.to_atom(val)))}
                    )

                "$count" ->
                  val = Enum.at(v, 0)

                  query =
                    from(
                      p in query,
                      select_merge: %{count: count(field(p, ^String.to_atom(val)))}
                    )

                "$min" ->
                  val = Enum.at(v, 0)

                  query =
                    from(
                      p in query,
                      select_merge: %{min: min(field(p, ^String.to_atom(val)))}
                    )

                "$max" ->
                  val = Enum.at(v, 0)

                  query =
                    from(
                      p in query,
                      select_merge: %{max: max(field(p, ^String.to_atom(val)))}
                    )

                "$sum" ->
                  val = Enum.at(v, 0)

                  query =
                    from(
                      p in query,
                      select_merge: %{sum: sum(field(p, ^String.to_atom(val)))}
                    )

                "$fields" ->
                  fields = Enum.at(v, 0)
                  IO.inspect(fields)
              end
            end)
           end)
         end

如果我 运行 这段代码没有 $fields 语句。 returns select 合并查询正确。

但如果我运行它与$fields。它给了我错误。

  (Protocol.UndefinedError) protocol Ecto.Queryable not implemented for [:id]

它将 $fields 的值作为我的模型名称并在查询中使用它

为什么会这样?以$fields的值作为我的模型

任何帮助将不胜感激。

谢谢。

您必须 return 任何具有 Ecto.Queryable 实现(即 Ecto.Query)并且您的代码当前正在 returning List (fields.)不要忘记 您在 reduce 中并且 returned 值是一个累加器。 FWIW,

"$fields" ->
  fields = Enum.at(v, 0)
  IO.inspect(fields)
  query   # ⇐ NOTE THE RETURNED VALUE 

在正确实施之前将用作存根。