Skip to content

Commit 787b4e4

Browse files
authored
Merge pull request #28 from sopaco/dev
Add timestamp fields and time range filtering to Qdrant vector store
2 parents 3c3c0f4 + 809c95e commit 787b4e4

1 file changed

Lines changed: 72 additions & 0 deletions

File tree

cortex-mem-core/src/vector_store/qdrant.rs

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)