bson是binary json的缩写,可以把它看做是键值对的组合,主要在mongodb做数据存储时用到,看了下Git上有人用erlang写了个bson,学习一下写法。
%% 这个函数时用来查找filed所对应的index的
find(Label, Doc) -> findN(Label, Doc, 0, tuple_size(Doc) div 2).
findN(Label, Doc, High, High) -> {};
findN(Label, Doc, Low, High) ->
case element(Low *2 +1 ,Doc) of
Label -> Low; %%这个地方找到了对应的Key,返回此Key对应的Index
AtomKey when is_atom(AtomKey) ->
case atom_to_bianry(AtomKey, utf8) =:= Label of
true -> Low;
false -> findN(Label, Doc, Low + 1, High)
end;
_ -> findN(Label, Doc, Low + 1, Hight)
end.
lookup(Label, Doc) ->
lookup(Label, Doc, []).
lookup(Label, Doc, Default) when is_atom(Label) ->
lookup(atom_to_binary(Label, utf8), Doc, Default);%%这个地方不用utf8编码也是可以的,因为当前erlang的atom范围完全够Latin编码,但是为了之后的使用,还是用的utf8
lookup(Label, Doc, Default) ->
Parts = binary:split(Label, <<".">>, []),
case length(Parts) of
1 ->
lookup(Parts, Doc, fun(Index) -> element(Index * 2 + 2, Doc) end, Default);%%当只有一个元素时,直接找Value中对应的元素就可以了。
_ ->
lookup(Parts, Doc, fun(Index) -> lookup(hd(tl(Parts)), element(Index * 2 + 2, Doc) end, Default) end, Deafault)%%当元素不止一个时,递归寻找
end.
%% 如果找到了对应的Index就执行Fun函数
lookup(Parts, Doc, GetFun, Default) ->
case find(hd(Parts), Doc) of
{} -> Default;
Index -> GetFun(Index)
end.