Cardinality Support?
criminosis opened this issue · 3 comments
This Cardinality to be clear
Right now it there doesn't seem to be deriving elements that are Vec<T>
or HashSet<T>
on structs as in stuff like Vec<String>
or a HashSet<String>
.
I was able to prove out something that appears to work with these:
fn for_list<T>(glist: List) -> GremlinResult<Vec<T>>
where
T: std::convert::TryFrom<GValue, Error = GremlinError>,
{
glist
.take()
.into_iter()
.map(|x| x.try_into())
.collect::<GremlinResult<Vec<T>>>()
}
fn for_list_to_set<T>(glist: List) -> GremlinResult<HashSet<T>>
where
T: std::convert::TryFrom<GValue, Error = GremlinError> + Hash + Eq,
{
glist
.take()
.into_iter()
.map(|x| x.try_into())
.collect::<GremlinResult<HashSet<T>>>()
}
fn for_set<T>(gset: Set) -> GremlinResult<HashSet<T>>
where
T: std::convert::TryFrom<GValue, Error = GremlinError> + Hash + Eq,
{
gset.take()
.into_iter()
.map(|x| x.try_into())
.collect::<GremlinResult<HashSet<T>>>()
}
macro_rules! impl_try_from_set {
($t:ty) => {
impl std::convert::TryFrom<GValue> for HashSet<$t> {
type Error = crate::GremlinError;
fn try_from(value: GValue) -> GremlinResult<Self> {
match value {
GValue::List(s) => for_list_to_set(s),
GValue::Set(s) => for_set(s),
_ => Err(GremlinError::Cast(format!(
"Cannot cast {:?} to Set",
value
))),
}
}
}
};
}
impl_try_from_set!(String);
impl_try_from_set!(i32);
impl_try_from_set!(i64);
macro_rules! impl_try_from_list {
($t:ty) => {
impl std::convert::TryFrom<GValue> for Vec<$t> {
type Error = crate::GremlinError;
fn try_from(value: GValue) -> GremlinResult<Self> {
match value {
GValue::List(s) => for_list(s),
_ => Err(GremlinError::Cast(format!(
"Cannot cast {:?} to Vec",
value
))),
}
}
}
};
}
impl_try_from_list!(String);
impl_try_from_list!(i32);
impl_try_from_list!(i64);
I could do another PR if there's interest in incorporating these. FWIW I was somewhat confused though by the logic here:
Seems like we shouldn't be attempting to parse List properties there? Maybe the PR should also remove that logic?
The main issue that I see with cardinality and multivalue properties for vertices is that they can contains different type for a key. So in case if your output is vec hashset of T you could not represent the different types
Probably the best way to approach this is to try to convert the multi-properties with tuples instead of vec or set. But in case o have to check more on this :)
that they can contains different type for a key
Could you elaborate @wolf4ood? I wouldn't expect that to be permitted. Like if you have a property of "names" and insert multiple values that would seem to forced to being String values due to the schema. Like here's a demonstration of what I mean. Even when I inserted an integer value 1234
(notice the lack of '
it when I inserted it) it coerced it into being a string to confirm to the type defined in the schema.
gremlin> g.addV('person').property(list, 'names', 'chris')
==>v[4168]
gremlin> g.V(4168).property('names', 'chris2')
==>v[4168]
gremlin> g.V(4168).valueMap()
==>{names=[chris, chris2]}
gremlin> g.V(4168).property('names', 1234)
==>v[4168]
gremlin> g.V(4168).valueMap()
==>{names=[chris, chris2, 1234]}
And then later when doing it for an integer property it rejected when I tried to insert a string:
gremlin> g.V(4168).property(set, 'numbers', 1234)
==>v[4168]
gremlin> g.V(4168).property(set, 'numbers', 589)
==>v[4168]
gremlin> g.V(4168).property(set, 'numbers', 'hello world')
Value [hello world] is not an instance of the expected data type for property key [numbers] and cannot be converted. Expected: class java.lang.Integer, found: class java.lang.String
Type ':help' or ':h' for help.
Display stack trace? [yN]n
Schema below:
gremlin> graph.openManagement().printSchema()
==>------------------------------------------------------------------------------------------------
Vertex Label Name | Partitioned | Static |
---------------------------------------------------------------------------------------------------
person | false | false |
---------------------------------------------------------------------------------------------------
Edge Label Name | Directed | Unidirected | Multiplicity |
---------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------
Property Key Name | Cardinality | Data Type |
---------------------------------------------------------------------------------------------------
names | LIST | class java.lang.String |
numbers | SET | class java.lang.Integer |
---------------------------------------------------------------------------------------------------
Vertex Index Name | Type | Unique | Backing | Key: Status |
---------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------
Edge Index (VCI) Name | Type | Unique | Backing | Key: Status |
---------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------
Relation Index | Type | Direction | Sort Key | Order | Status |
---------------------------------------------------------------------------------------------------
Admittedly this from using a JanusGraph setup