mirror of
https://github.com/quickwit-oss/tantivy.git
synced 2026-05-17 16:50:41 +00:00
allow histogram bounds to be passed as Rfc3339 (#2076)
This commit is contained in:
@@ -604,6 +604,42 @@ mod tests {
|
||||
});
|
||||
assert_eq!(res, expected_res);
|
||||
}
|
||||
|
||||
{
|
||||
// 1day + hard_bounds as Rfc3339
|
||||
let elasticsearch_compatible_json = json!(
|
||||
{
|
||||
"sales_over_time": {
|
||||
"date_histogram": {
|
||||
"field": "date",
|
||||
"fixed_interval": "1d",
|
||||
"hard_bounds": {
|
||||
"min": "2015-01-02T00:00:00Z",
|
||||
"max": "2015-01-02T12:00:00Z"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
let agg_req: Aggregations = serde_json::from_str(
|
||||
&serde_json::to_string(&elasticsearch_compatible_json).unwrap(),
|
||||
)
|
||||
.unwrap();
|
||||
let res = exec_request(agg_req, &index).unwrap();
|
||||
let expected_res = json!({
|
||||
"sales_over_time" : {
|
||||
"buckets": [
|
||||
{
|
||||
"doc_count": 1,
|
||||
"key": 1420156800000.0,
|
||||
"key_as_string": "2015-01-02T00:00:00Z"
|
||||
}
|
||||
]
|
||||
}
|
||||
});
|
||||
assert_eq!(res, expected_res);
|
||||
}
|
||||
}
|
||||
#[test]
|
||||
fn histogram_test_invalid_req() {
|
||||
|
||||
@@ -177,11 +177,38 @@ impl HistogramAggregation {
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize)]
|
||||
pub struct HistogramBounds {
|
||||
/// The lower bounds.
|
||||
#[serde(deserialize_with = "deserialize_date_or_num")]
|
||||
pub min: f64,
|
||||
/// The upper bounds.
|
||||
#[serde(deserialize_with = "deserialize_date_or_num")]
|
||||
pub max: f64,
|
||||
}
|
||||
|
||||
fn deserialize_date_or_num<'de, D>(deserializer: D) -> Result<f64, D::Error>
|
||||
where D: serde::Deserializer<'de> {
|
||||
let value: serde_json::Value = Deserialize::deserialize(deserializer)?;
|
||||
|
||||
// Check if the value is a string representing an Rfc3339 formatted date
|
||||
if let serde_json::Value::String(date_str) = value {
|
||||
// Parse the Rfc3339 formatted date string into a DateTime<Utc>
|
||||
let date =
|
||||
time::OffsetDateTime::parse(&date_str, &time::format_description::well_known::Rfc3339)
|
||||
.map_err(|_| serde::de::Error::custom("Invalid Rfc3339 formatted date"))?;
|
||||
|
||||
let milliseconds: i64 = (date.unix_timestamp_nanos() / 1_000_000)
|
||||
.try_into()
|
||||
.map_err(|_| serde::de::Error::custom("{date_str} out of allowed range"))?;
|
||||
|
||||
// Return the milliseconds as f64
|
||||
Ok(milliseconds as f64)
|
||||
} else {
|
||||
// The value is not a string, so assume it's a regular f64 number
|
||||
value
|
||||
.as_f64()
|
||||
.ok_or_else(|| serde::de::Error::custom("Invalid number format"))
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for HistogramBounds {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.write_fmt(format_args!("[{},{}]", self.min, self.max))
|
||||
|
||||
Reference in New Issue
Block a user