Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/elixir/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mongodb 使用Jason在Phoenix中编码ObjectId_Mongodb_Elixir_Phoenix Framework - Fatal编程技术网

Mongodb 使用Jason在Phoenix中编码ObjectId

Mongodb 使用Jason在Phoenix中编码ObjectId,mongodb,elixir,phoenix-framework,Mongodb,Elixir,Phoenix Framework,我在凤凰城有一个频道,在那里我从MongoDB获取对象列表: cursor = Mongo.find(:mongo, "ledgers", %{}) list = Enum.to_list(cursor) 我尝试发送以下邮件: broadcast(socket, "load_ledgers_do", %{payload: list}) 这将返回错误: [error] GenServer #PID<0.3147.0> terminating

我在凤凰城有一个频道,在那里我从MongoDB获取对象列表:

cursor = Mongo.find(:mongo, "ledgers", %{})
list = Enum.to_list(cursor)
我尝试发送以下邮件:

broadcast(socket, "load_ledgers_do", %{payload: list})
这将返回错误:

[error] GenServer #PID<0.3147.0> terminating
** (Protocol.UndefinedError) protocol Jason.Encoder not implemented for #BSON.ObjectId<603e521606fc6d39bd3e641d> of type BSON.ObjectId (a struct), Jason.Encoder protocol must always be explicitly implemented.

If you own the struct, you can derive the implementation specifying which fields should be encoded to JSON:

    @derive {Jason.Encoder, only: [....]}
    defstruct ...

It is also possible to encode all fields, although this should be used carefully to avoid accidentally leaking private information when new fields are added:

    @derive Jason.Encoder
    defstruct ...

Finally, if you don't own the struct you want to encode to JSON, you may use Protocol.derive/3 placed outside of any module:

    Protocol.derive(Jason.Encoder, NameOfTheStruct, only: [...])
    Protocol.derive(Jason.Encoder, NameOfTheStruct)
但这会返回一个错误。确保objectid正确编码的最佳方法是什么

编辑错误:

[error] Ranch listener ServerWeb.Endpoint.HTTP had connection process started with :cowboy_clear:start_link/4 at #PID<0.3641.0> exit with reason: {:badarg, [{:erlang, :iolist_size, [[91, "null", 44, "null", 44, [34, [[] | "ledgers"], 34], 44, [34, [[] | "load_ledgers_do"], 34], 44, ["{\"", [[] | "payload"], "\":", [91, ["{\"", [[] | "_id"], "\":", {:ok, "\"603e521606fc6d39bd3e641d\""}, ",\"", [[] | "collection"], "\":", [34, [[] | "ledger_603e521606fc6d39bd3e641d"], 34], ",\"", [[] | "columns"], "\":", "[]", ",\"", [[] | "name"], "\":", [34, [[] | "Ledger1"], 34], ",\"", [[] | "x"], "\":", "427", ",\"", [[] | "y"], "\":", "283", 125], 93], 125], 93]], []}, {:cow_ws, :payload_length, 1, [file: '/home/lars/bdrp/server/deps/cowlib/src/cow_ws.erl', line: 725]}, {:cow_ws, :frame, 2, [file: '/home/lars/bdrp/server/deps/cowlib/src/cow_ws.erl', line: 666]}, {:cowboy_websocket, :websocket_send, 2, [file: '/home/lars/bdrp/server/deps/cowboy/src/cowboy_websocket.erl', line: 626]}, {:cowboy_websocket, :handler_call, 6, [file: '/home/lars/bdrp/server/deps/cowboy/src/cowboy_websocket.erl', line: 542]}, {:cowboy_http, :loop, 1, [file: '/home/lars/bdrp/server/deps/cowboy/src/cowboy_http.erl', line: 254]}, {:proc_lib, :init_p_do_apply, 3, [file: 'proc_lib.erl', line: 226]}]}

[error] GenServer #PID<0.3644.0> terminating
** (ArgumentError) argument error
:erlang.iolist_size([91, "null", 44, "null", 44, [34, [[] | "ledgers"], 34], 44, [34, [[] | "load_ledgers_do"], 34], 44, ["{\"", [[] | "payload"], "\":", [91, ["{\"", [[] | "_id"], "\":", {:ok, "\"603e521606fc6d39bd3e641d\""}, ",\"", [[] | "collection"], "\":", [34, [[] | "ledger_603e521606fc6d39bd3e641d"], 34], ",\"", [[] | "columns"], "\":", "[]", ",\"", [[] | "name"], "\":", [34, [[] | "Ledger1"], 34], ",\"", [[] | "x"], "\":", "427", ",\"", [[] | "y"], "\":", "283", 125], 93], 125], 93])
(cowlib 2.9.1) /home/lars/bdrp/server/deps/cowlib/src/cow_ws.erl:725: :cow_ws.payload_length/1
(cowlib 2.9.1) /home/lars/bdrp/server/deps/cowlib/src/cow_ws.erl:666: :cow_ws.frame/2
(cowboy 2.8.0) /home/lars/bdrp/server/deps/cowboy/src/cowboy_websocket.erl:626: :cowboy_websocket.websocket_send/2
(cowboy 2.8.0) /home/lars/bdrp/server/deps/cowboy/src/cowboy_websocket.erl:542: :cowboy_websocket.handler_call/6
(cowboy 2.8.0) /home/lars/bdrp/server/deps/cowboy/src/cowboy_http.erl:254: :cowboy_http.loop/1
(stdlib 3.13) proc_lib.erl:226: :proc_lib.init_p_do_apply/3
Last message: {:DOWN, #Reference<0.3631150579.3565682692.115779>, :process, #PID<0.3641.0>, {:badarg, [{:erlang, :iolist_size, [[91, "null", 44, "null", 44, [34, [[] | "ledgers"], 34], 44, [34, [[] | "load_ledgers_do"], 34], 44, ["{\"", [[] | "payload"], "\":", [91, ["{\"", [[] | "_id"], "\":", {:ok, "\"603e521606fc6d39bd3e641d\""}, ",\"", [[] | "collection"], "\":", [34, [[] | "ledger_603e521606fc6d39bd3e641d"], 34], ",\"", [[] | "columns"], "\":", "[]", ",\"", [[] | "name"], "\":", [34, [[] | "Ledger1"], 34], ",\"", [[] | "x"], "\":", "427", ",\"", [...], ...], 93], 125], 93]], []}, {:cow_ws, :payload_length, 1, [file: '/home/lars/bdrp/server/deps/cowlib/src/cow_ws.erl', line: 725]}, {:cow_ws, :frame, 2, [file: '/home/lars/bdrp/server/deps/cowlib/src/cow_ws.erl', line: 666]}, {:cowboy_websocket, :websocket_send, 2, [file: '/home/lars/bdrp/server/deps/cowboy/src/cowboy_websocket.erl', line: 626]}, {:cowboy_websocket, :handler_call, 6, [file: '/home/lars/bdrp/server/deps/cowboy/src/cowboy_websocket.erl', line: 542]}, {:cowboy_http, :loop, 1, [file: '/home/lars/bdrp/server/deps/cowboy/src/cowboy_http.erl', line: 254]}, {:proc_lib, :init_p_do_apply, 3, [file: 'proc_lib.erl', line: 226]}]}}
State: %Phoenix.Socket{assigns: %{}, channel: ServerWeb.LedgersChannel, channel_pid: #PID<0.3644.0>, endpoint: ServerWeb.Endpoint, handler: ServerWeb.UserSocket, id: nil, join_ref: "141", joined: true, private: %{log_handle_in: :debug, log_join: :info}, pubsub_server: Server.PubSub, ref: nil, serializer: Phoenix.Socket.V2.JSONSerializer, topic: "ledgers", transport: :websocket, transport_pid: #PID<0.3641.0>}

到目前为止,我还没有摆脱它。

这有点棘手,因为二进制ID的编码并不总是很好

您正在使用哪个Mongo库?如果您正在使用,可以使用其
BSON.encode/1
帮助转换二进制文件,您可以尝试以下操作:

defimpl Jason.Encoder, for: BSON.ObjectId do
  def encode(val, _opts \\ []) do
    val
    |> BSON.encode()
    |> Base.encode16(case: :lower)
  end
end
iex>o=%BSON.ObjectId{value:}
#BSON.ObjectId
iex>Jason.encode(o)
{:好的,“5e30632e7437079954f61236”}

让它开始工作。这似乎是一个正确的解决方案:

defimpl Jason.Encoder, for: BSON.ObjectId do
  def encode(val, _opts \\ []) do
    BSON.ObjectId.encode!(val)
    |> Jason.encode!()
  end
end

感叹号丢失。

“这返回了一个错误”-请显示它返回了什么错误。已使用错误日志进行了更新。它没有完全起作用,但它让我找到了正确的方向。非常感谢。
defimpl Jason.Encoder, for: BSON.ObjectId do
  def encode(val, _opts \\ []) do
    val
    |> BSON.encode()
    |> Base.encode16(case: :lower)
  end
end
iex> o = %BSON.ObjectId{value: <<94, 48, 99, 46, 116, 55, 7, 153, 84, 246, 18, 54>>}
#BSON.ObjectId<5e30632e7437079954f61236>
iex> Jason.encode(o)
{:ok, "5e30632e7437079954f61236"}
defimpl Jason.Encoder, for: BSON.ObjectId do
  def encode(val, _opts \\ []) do
    BSON.ObjectId.encode!(val)
    |> Jason.encode!()
  end
end