Mongo中BsonString类型日期字段如何用DateTime做Filter查询?
dateCreated is Stored as BsonString (C#) Hey there! Let's break down why you're hitting that InvalidOperationException: Sequence contains no elements error first, then walk through the solutions.
Why the Error Happens
Your current filter tries to treat dateCreated as a BsonDateTime using x["dateCreated"].AsBsonDateTime, but the field is actually stored as a BsonString. MongoDB can't implicitly convert a string to a date for comparison, so your filter doesn't match any documents—hence the "no elements" error.
Solution 1: Convert String to Date Directly in the MongoDB Query (Recommended)
Use MongoDB's $dateFromString operator to convert the string field to a date during the query. This keeps processing on the database side (efficient even for large datasets) and lets you compare dates properly.
Here's the adjusted code:
// Define your target cutoff date var cutoffDate = DateTime.Today.AddDays(-10000); // Build the filter using $expr to handle date conversion var filter = new BsonDocument { { "$expr", new BsonDocument { { "$gte", new BsonArray { // Convert the dateCreated string to a MongoDB date new BsonDocument("$dateFromString", new BsonDocument { { "dateString", "$dateCreated" }, // Optional: Add this if your date string uses a custom format (e.g., "yyyy-MM-dd HH:mm:ss") // { "format", "%Y-%m-%d %H:%M:%S" } }), // Compare against your cutoff date (MongoDB auto-converts this to BsonDateTime) cutoffDate } } } } }; // Execute the query safely var modelsCursor = await c.FindAsync(filter); var modelsList = await modelsCursor.ToListAsync(); // Check for results before accessing First() if (modelsList.Any()) modelsList.First().Dump(); else Console.WriteLine("No documents match the date filter.");
Key Notes:
- If your
dateCreatedstring uses a non-standard format (e.g.,MM/dd/yyyy), must add theformatparameter to$dateFromString—otherwise MongoDB might fail to parse the string correctly. - This method works with indexes if you create one on the converted date (or better, on the field once you fix the type).
Solution 2: Filter After Fetching All Documents (Only for Small Datasets)
If your collection is tiny and performance isn't a concern, you can fetch all documents first, then convert the string to a date in C# and filter locally:
// Fetch all documents from the collection var allDocuments = await c.Find(_ => true).ToListAsync(); // Filter in C# by parsing the string to BsonDateTime var filteredDocuments = allDocuments.Where(doc => { // Try to parse the string to a valid date if (BsonDateTime.TryParse(doc["dateCreated"].AsString, out var parsedDate)) { return parsedDate >= DateTime.Today.AddDays(-10000); } // Skip documents with invalid date strings return false; }).ToList(); if (filteredDocuments.Any()) filteredDocuments.First().Dump(); else Console.WriteLine("No matching documents found.");
⚠️ Warning: This pulls every document from the database to your application—never use this for large collections as it will cripple performance.
Solution 3: Fix the Storage Type (Long-Term Best Practice)
The cleanest solution is to convert the dateCreated field from BsonString to BsonDateTime permanently. This eliminates conversion headaches and lets you use efficient date queries/indexes going forward.
Here's a migration script to update all documents:
// Build the update to convert string dates to BsonDateTime var update = new BsonDocument { { "$set", new BsonDocument { { "dateCreated", new BsonDocument("$dateFromString", new BsonDocument { { "dateString", "$dateCreated" }, // Add your custom date format here if needed // { "format", "%Y-%m-%d %H:%M:%S" } }) } } } }; // Update all documents in the collection var updateResult = await c.UpdateManyAsync(_ => true, update); Console.WriteLine($"Updated {updateResult.ModifiedCount} documents to use BsonDateTime for dateCreated.");
After running this, your original filter (using Gte(x => x["dateCreated"].AsBsonDateTime, ...)) will work perfectly, and you can create an index on dateCreated to speed up future queries.
内容的提问来源于stack exchange,提问作者Royi Namir

