MongoDB查询验证器未校验数组内每个对象约束的技术问询
The core issue with your existing validators is that they only check if at least one element in the address array meets the zipcode requirement, not every element. For example, $elemMatch confirms there's at least one valid entry, but allows others to be invalid. Similarly, address.zipcode checks if any zipcode exists as a number, not all.
Here's the corrected validator that ensures every object in the address array has a valid numeric zipcode, along with proper validation settings to enforce strict checks:
db.createCollection("person_details_correct", { validator: { $and: [ // Ensure name is a string { name: { $type: "string" } }, // Ensure address is an array (fixes redundant $type check in original code) { address: { $type: "array" } }, // Ensure NO elements in address are missing zipcode or have non-numeric zipcode { address: { $not: { $elemMatch: { $or: [ { zipcode: { $exists: false } }, { zipcode: { $not: { $type: "number" } } } ] } } } } ] }, // Enforce validation on all inserts/updates (not just inserts) validationLevel: "strict", // Block invalid operations instead of just warning validationAction: "error" });
How This Works:
$not + $elemMatch: This combination inverts the check—instead of looking for valid elements, it ensures there are no elements that violate the zipcode rules. If any element is missingzipcodeor has a non-numeric value, the validation fails.- Fixed
addresstype check: The original code used{$type:'array',$type:'object'}which is redundant (a field can't be both an array and object). We only check thataddressis an array.
Test the Invalid Insert:
When you run the problematic insert:
db.person_details_correct.insert({ name: 'arav', address: [{ zipcode: 23213 },{ name: 'ewef' }] });
You'll get a validation error like:WriteError({ "code" : 121, "errmsg" : "Document failed validation" })
This confirms the validator now blocks entries where any address element lacks a valid zipcode.
内容的提问来源于stack exchange,提问作者Aravind Rajagopalan

