使用Spring Boot定义带JSON Schema校验的MongoDB集合
If you want to set up MongoDB's native JSON Schema validation directly when creating a collection (bypassing JSR-303 bean validations like Spring Data MongoDB's @NotNull), here's a practical implementation that ensures the validation rule is embedded in the collection and can be retrieved via CollectionInfos():
Step 1: Define Your JSON Schema
First, craft the JSON Schema that matches your Account entity's constraints. For example, if your Account has an _id, required email (with valid format), and a non-negative balance, the schema would look like this:
{ "$jsonSchema": { "bsonType": "object", "required": ["email"], "properties": { "_id": { "bsonType": "objectId" }, "email": { "bsonType": "string", "description": "Must be a valid email address and is required", "pattern": "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$" }, "balance": { "bsonType": "double", "description": "Must be a non-negative number", "minimum": 0 } } } }
Step 2: Create the Collection with Validation in Spring Boot
Use MongoTemplate to create the collection with the schema validation rules. You can do this in a configuration class or an application runner to ensure it runs on startup:
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.ApplicationArguments; import org.springframework.boot.ApplicationRunner; import org.springframework.context.annotation.Configuration; import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.data.mongodb.core.collection.CollectionOptions; import org.springframework.data.mongodb.core.schema.MongoJsonSchema; @Configuration public class MongoCollectionSetup implements ApplicationRunner { @Autowired private MongoTemplate mongoTemplate; @Override public void run(ApplicationArguments args) throws Exception { // Parse the JSON schema into a MongoJsonSchema object MongoJsonSchema schema = MongoJsonSchema.builder() .schemaJson(""" { "$jsonSchema": { "bsonType": "object", "required": ["email"], "properties": { "_id": { "bsonType": "objectId" }, "email": { "bsonType": "string", "description": "Must be a valid email address and is required", "pattern": "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\\\.[a-zA-Z]{2,}$" }, "balance": { "bsonType": "double", "description": "Must be a non-negative number", "minimum": 0 } } } } """) .build(); // Create the collection with validation options CollectionOptions options = CollectionOptions.empty() .validationOptions(CollectionOptions.ValidationOptions.schema(schema)); // Only create if the collection doesn't exist already if (!mongoTemplate.collectionExists(Account.class)) { mongoTemplate.createCollection(Account.class, options); } } }
Make sure your Account entity is mapped correctly (with @Document if needed):
import org.springframework.data.annotation.Id; import org.springframework.data.mongodb.core.mapping.Document; @Document(collection = "accounts") public class Account { @Id private String id; private String email; private Double balance; // Getters, setters, constructors }
Step 3: Verify the Validation Rule
Test Invalid Data Insertion
Try inserting an Account without an email or with a negative balance—MongoDB should throw a validation exception:
Account invalidAccount = new Account(); invalidAccount.setBalance(-100.0); try { mongoTemplate.save(invalidAccount); } catch (Exception e) { // Should catch a MongoWriteException due to schema validation failure System.out.println("Validation failed as expected: " + e.getMessage()); }
Retrieve Validation Schema via CollectionInfos()
To check the schema in JSON format, use MongoTemplate to fetch collection info and extract the validation rule:
import org.springframework.data.mongodb.core.MongoTemplate; import com.mongodb.client.MongoCollection; import org.bson.Document; import java.util.ArrayList; // Inside your service/runner MongoCollection<Document> collection = mongoTemplate.getCollection("accounts"); Document collectionInfo = mongoTemplate.getDb().runCommand(new Document("listCollections", 1) .append("filter", new Document("name", "accounts"))); // Extract and print the validation schema Document cursorDoc = (Document) collectionInfo.get("cursor"); ArrayList<Document> firstBatch = (ArrayList<Document>) cursorDoc.get("firstBatch"); Document accountCollectionInfo = firstBatch.get(0); Document validationSchema = accountCollectionInfo.get("validator", Document.class); System.out.println("Collection Validation Schema: " + validationSchema.toJson());
This will output the exact JSON schema you configured, confirming it's applied to the collection.
内容的提问来源于stack exchange,提问作者Federico Gatti

