@@ -174,6 +174,16 @@ impl QdrantVectorStore {
174174 memory. updated_at . to_rfc3339 ( ) . into ( ) ,
175175 ) ;
176176
177+ // Numeric timestamps for efficient range filtering
178+ payload. insert (
179+ "created_at_ts" . to_string ( ) ,
180+ ( memory. created_at . timestamp_millis ( ) as i64 ) . into ( ) ,
181+ ) ;
182+ payload. insert (
183+ "updated_at_ts" . to_string ( ) ,
184+ ( memory. updated_at . timestamp_millis ( ) as i64 ) . into ( ) ,
185+ ) ;
186+
177187 // Metadata fields
178188 if let Some ( user_id) = & memory. metadata . user_id {
179189 payload. insert ( "user_id" . to_string ( ) , user_id. clone ( ) . into ( ) ) ;
@@ -290,6 +300,68 @@ impl QdrantVectorStore {
290300 } ) ;
291301 }
292302
303+ // Time range filters
304+ // NOTE: Qdrant Range filters require numeric fields, so we filter on *_ts (milliseconds since epoch)
305+ if let Some ( created_after) = filters. created_after {
306+ conditions. push ( Condition {
307+ condition_one_of : Some ( condition:: ConditionOneOf :: Field ( FieldCondition {
308+ key : "created_at_ts" . to_string ( ) ,
309+ range : Some ( Range {
310+ gt : None ,
311+ gte : Some ( created_after. timestamp_millis ( ) as f64 ) ,
312+ lt : None ,
313+ lte : None ,
314+ } ) ,
315+ ..Default :: default ( )
316+ } ) ) ,
317+ } ) ;
318+ }
319+
320+ if let Some ( created_before) = filters. created_before {
321+ conditions. push ( Condition {
322+ condition_one_of : Some ( condition:: ConditionOneOf :: Field ( FieldCondition {
323+ key : "created_at_ts" . to_string ( ) ,
324+ range : Some ( Range {
325+ gt : None ,
326+ gte : None ,
327+ lt : None ,
328+ lte : Some ( created_before. timestamp_millis ( ) as f64 ) ,
329+ } ) ,
330+ ..Default :: default ( )
331+ } ) ) ,
332+ } ) ;
333+ }
334+
335+ if let Some ( updated_after) = filters. updated_after {
336+ conditions. push ( Condition {
337+ condition_one_of : Some ( condition:: ConditionOneOf :: Field ( FieldCondition {
338+ key : "updated_at_ts" . to_string ( ) ,
339+ range : Some ( Range {
340+ gt : None ,
341+ gte : Some ( updated_after. timestamp_millis ( ) as f64 ) ,
342+ lt : None ,
343+ lte : None ,
344+ } ) ,
345+ ..Default :: default ( )
346+ } ) ) ,
347+ } ) ;
348+ }
349+
350+ if let Some ( updated_before) = filters. updated_before {
351+ conditions. push ( Condition {
352+ condition_one_of : Some ( condition:: ConditionOneOf :: Field ( FieldCondition {
353+ key : "updated_at_ts" . to_string ( ) ,
354+ range : Some ( Range {
355+ gt : None ,
356+ gte : None ,
357+ lt : None ,
358+ lte : Some ( updated_before. timestamp_millis ( ) as f64 ) ,
359+ } ) ,
360+ ..Default :: default ( )
361+ } ) ) ,
362+ } ) ;
363+ }
364+
293365 // Filter by topics - check if any of the requested topics are present
294366 if let Some ( topics) = & filters. topics {
295367 if !topics. is_empty ( ) {
0 commit comments