Error when grouping using Query.jl

Let the data sourse be a list of Dicts:

julia> as = [Dict("id" => "a", "v" => 1), 
             Dict("id" => "b", "v" => 2)]

Then we group them by id

julia> using Query

julia> @from a in as begin
       @group a by a["id"]
       @collect
       end
ERROR: MethodError: Cannot `convert` an object of type Query.Grouping{String,Dict{String,Any}} to an object of type Query.Grouping{Any,Dict{String,Any}}
This may have arisen from a call to the constructor Query.Grouping{Any,Dict{String,Any}}(...),
since type constructors fall back to convert methods.
Stacktrace:
 [1] setindex!(::DataStructures.OrderedDict{Any,Query.Grouping{Any,Dict{String,Any}}}, ::Query.Grouping{String,Dict{String,Any}}, ::String) at /home/lizz/.julia/v0.6/DataStructures/src/ordered_dict.jl:310
 [2] start(::Query.EnumerableGroupBySimple{Query.Grouping{Any,Dict{String,Any}},Any,Dict{String,Any},Query.EnumerableIterable{Dict{String,Any},Array{Dict{String,Any},1}},##3#4}) at /home/lizz/.julia/v0.6/Query/src/enumerable/enumerable_groupby.jl:41
 [3] collect(::Query.EnumerableGroupBySimple{Query.Grouping{Any,Dict{String,Any}},Any,Dict{String,Any},Query.EnumerableIterable{Dict{String,Any},Array{Dict{String,Any},1}},##3#4}) at /home/lizz/.julia/v0.6/Query/src/sinks/sink_array.jl:4

I think, this is a bug?

A workaround is

julia> @from a in as begin
       @group a by Any[a["id"]]
       @collect
       end
2-element Array{Query.Grouping{Array{Any,1},Dict{String,Any}},1}:
 Dict{String,Any}[Dict{String,Any}(Pair{String,Any}("v", 1),Pair{String,Any}("id", "a"))]
 Dict{String,Any}[Dict{String,Any}(Pair{String,Any}("v", 2),Pair{String,Any}("id", "b"))]

The background is, the data I work with is from mongodb. And they are all converted to Dicts.


The following is not important, but interesting.
If we group by v, we still get error

julia> @from a in as begin
       @group a by a["v"]
       @collect
       end
ERROR: MethodError: Cannot `convert` an object of type Query.Grouping{Int64,Dict{String,Any}} to an object of type Query.Grouping{Any,Dict{String,Any}}
This may have arisen from a call to the constructor Query.Grouping{Any,Dict{String,Any}}(...),
since type constructors fall back to convert methods.

We can fix this by giving a["v"] an explicit type Int(a["v"]).

julia> @from a in as begin
       @group a by Int(a["v"])
       @collect
       end
2-element Array{Query.Grouping{Int64,Dict{String,Any}},1}:
 Dict{String,Any}[Dict{String,Any}(Pair{String,Any}("v", 1),Pair{String,Any}("id", "a"))]
 Dict{String,Any}[Dict{String,Any}(Pair{String,Any}("v", 2),Pair{String,Any}("id", "b"))]

However, this does not work for strings, and I cannot guess the reason

julia> @from a in as begin
       @group a by String(a["id"])
       @collect
       end
ERROR: MethodError: Cannot `convert` an object of type Query.Grouping{String,Dict{String,Any}} to an object of type Query.Grouping{Any,Dict{String,Any}}
This may have arisen from a call to the constructor Query.Grouping{Any,Dict{String,Any}}(...),
since type constructors fall back to convert methods.

Yes, that is a bug, thanks for finding and reporting it! I just fixed it and am just waiting for the bug fix release to be merged: https://github.com/JuliaLang/METADATA.jl/pull/11146.

To force the types in this case, you can use the following sytnax: a["id"]::String and a["v"]::Int.

1 Like