This message was deleted.
# general
s
This message was deleted.
b
There are some very nice blogs written by @Hellmar Becker. There are 5 parts and all the links present inside this blog: https://blog.hellmar-becker.de/2021/08/07/multivalue-dimensions-in-apache-druid-part-1/
c
to clarify multi-value string columns aren’t real arrays, though you can make them behave as string arrays, though they still have a lot of quirks
only reason i’m calling this out is because i have been working on adding real array typed columns that behave consistent with more normal SQL array types, though they are still a bit experimental
https://druid.apache.org/docs/latest/querying/sql-data-types.html#multi-value-strings-behavior has some details about multi-value string behavior, though its missing the parts about the newer array columns since they are still experimental
array columns should be more fully featured in druid 27 release, which is coming soon
there are some differences between how multi-value columns and array columns are stored, and multi-value columns are limited to string type
internally multi-value string columns are stored a lot like regular string columns, both of which are dictionary encoded with 3 main parts, the column itself composed of the dictionary ids, the value dictionary which can lookup dictionary ids, and bitmap indexes corresponding to which rows of the id column contain which values
the dictionary id column part of multi-value columns stores arrays of ints instead of individual int values
so seeking to specific rows is a bit more complicated of an operation
h
how is an array of string stored, as opposed to MVD? or would it also have an array of int IDs?
c
the multi-value columns sort of has two chunks of ints, one for the offsets of each int array, and then the chunks of int arrays themselves
array columns have lineage from nested columns
nested columns have sequentially stacked value dictionaries for each primitive type of value, so a string dictionary for all the string values, a long dictionary, double dictionary, and then an array dictionary which stores int[] whose values are pointers into the other dictionaries
h
to clarify, do you mean, one array per subcolumn and type? or just one big array per type?
c
nested columns are a bit more complicated, but when there is no actual nesting, then they sort of look a lot like single value string dictionary encoded columns
h
(forgive me for my limited understanding)
c
so for an array column, it uses that single value dictionary id column https://github.com/apache/druid/blob/master/processing/src/main/java/org/apache/druid/segment/data/CompressedVSizeColumnarIntsSupplier.java because each row is a dictionary id that points to an entire array
https://github.com/apache/druid/issues/12695 has the design on full nested columns, the new in druid 26 ‘auto’ schema has specializations for when there is no nesting, which is currently the only way to make array columns
so for array columns, instead of reading the row being an array of ints corresponding to dictionary id values, reading the row is a single int, which lookups into an int array, which each element is then looked up to get the element values
https://github.com/apache/druid/pull/13803 describes nested array columns, but ‘top level’ array columns are pretty similar
https://github.com/apache/druid/blob/master/processing/src/main/java/org/apache/druid/segment/nested/VariantColumn.java is the column implementation itself, currently it just shares with the mixed type column since they both need a lot of of the same stuff
disclaimer, filtering on array columns is basically broken in druid 26, but i hope it to be fixed in druid 27. it is not currently well wired up, but array columns have indexes both for whole array values and individual elements, while multi-value columns can only filter on individual elements, where if any value in the row matches the whole row matches (which can often create confusion of ‘how did that value match’ when coupled with the implicit UNNEST behavior that mvds have)
i guess the tl;dr is the biggest difference between mvds and arrays (besides the fact that arrays can distinguish
null
,
[]
, and
[null]
) is that rows for mvds are stored as
int[]
, which means the row is composed of multiple values, while rows of array columns store a single
int
meaning the entire array is a single value
h
okay, so … for a nested subcolumn $.a, even if row 1 has { “a” : 1 }, and row 2 has { “a”: “test” }, it would still all go into the sub-file for nested_a … and the first one would index into the integer part of the value array, and the second one goes into the string part?
c
yea basically
nested columns are a bit more complicated so i glossed over it a bit, each path basically has a local dictionary which maps to the “global” dictionary space that is shared by all paths in the column
but the column of
'$.a'
would be like
[2, 1]
if it was two rows and the global dictionaries contained only those two values (and null, which is always 0)
the array dictionary stores int[] which contain the ids of the elements, so if the 3rd row was
{"a":[1]}
, the array dictionary would now have id
3
which stores`[2]` (assuming
2
is still the dictionary id of our
1
value (heh confusing :p)
h
and what if, like above, the column of
'$.a'
has an int, but then in another row, a string?
v
Does Druid 0.18.1 version supports multi-value Dimensions?
h
I am pretty sure it does