diff --git a/lib/collection/src/operations/universal_query/formula.rs b/lib/collection/src/operations/universal_query/formula.rs index 4705014cab..45d9ae12d5 100644 --- a/lib/collection/src/operations/universal_query/formula.rs +++ b/lib/collection/src/operations/universal_query/formula.rs @@ -92,6 +92,7 @@ impl ExpressionInternal { by_zero_default, ), ExpressionInternal::GeoDistance { origin, to } => { + payload_vars.insert(to.clone()); ParsedExpression::new_geo_distance(origin, to) } ExpressionInternal::Sqrt(expression_internal) => ParsedExpression::Sqrt(Box::new( diff --git a/lib/segment/src/index/query_optimization/rescore_formula/value_retriever.rs b/lib/segment/src/index/query_optimization/rescore_formula/value_retriever.rs index b18f0f726f..f3e984148c 100644 --- a/lib/segment/src/index/query_optimization/rescore_formula/value_retriever.rs +++ b/lib/segment/src/index/query_optimization/rescore_formula/value_retriever.rs @@ -75,6 +75,16 @@ fn payload_variable_retriever( |payload| { let values = payload.get_value(&json_path); let value = *values.first()?; + + // not using array wildcard `[]` on a key which has an array value will return the whole + // array as one value, let's extract the first element if that is the case. + match value { + serde_json::Value::Array(array) if !json_path.has_wildcard_suffix() => { + return array.first().cloned(); + } + _ => {} + } + Some(value.clone()) }, hw_counter, @@ -253,12 +263,12 @@ mod tests { payload_provider.clone(), &hw_counter, ); - for id in 0..2 { + for id in 0..=2 { let value = retriever(id); match id { 0 => assert_eq!(value, Some(json!(42))), 1 => assert_eq!(value, None), - 2 => assert_eq!(value, Some(json!(99.0))), + 2 => assert_eq!(value, Some(json!(99))), _ => unreachable!(), } } @@ -270,7 +280,7 @@ mod tests { payload_provider.clone(), &hw_counter, ); - for id in 0..2 { + for id in 0..=2 { let value = retriever(id); match id { 0 => assert_eq!(value, None), @@ -324,7 +334,7 @@ mod tests { payload_provider.clone(), &hw_counter, ); - for id in 0..2 { + for id in 0..=2 { let value = retriever(id); match id { 0 => assert_eq!(value, Some(json!(42))), @@ -341,7 +351,7 @@ mod tests { payload_provider.clone(), &hw_counter, ); - for id in 0..2 { + for id in 0..=2 { let value = retriever(id); match id { 0 => assert_eq!(value, None), diff --git a/lib/segment/src/json_path/mod.rs b/lib/segment/src/json_path/mod.rs index c1a9dba0d7..6d841c93bc 100644 --- a/lib/segment/src/json_path/mod.rs +++ b/lib/segment/src/json_path/mod.rs @@ -171,6 +171,10 @@ impl JsonPath { result } + pub fn has_wildcard_suffix(&self) -> bool { + self.rest.last() == Some(&JsonPathItem::WildcardIndex) + } + /// Check if a path is included in a list of patterns. /// /// Basically, it checks if either the pattern or path is a prefix of the other.