最新的稳定版请使用 Spring Data MongoDB 4.3.1Spring中文文档

最新的稳定版请使用 Spring Data MongoDB 4.3.1Spring中文文档

从版本 3.6 开始,MongoDB 支持根据提供的 JSON 架构验证文档的集合。 在创建集合时,可以定义架构本身以及验证操作和级别,如以下示例所示:Spring中文文档

例 1.示例 JSON 架构
{
  "type": "object",                                                        (1)

  "required": [ "firstname", "lastname" ],                                 (2)

  "properties": {                                                          (3)

    "firstname": {                                                         (4)
      "type": "string",
      "enum": [ "luke", "han" ]
    },
    "address": {                                                           (5)
      "type": "object",
      "properties": {
        "postCode": { "type": "string", "minLength": 4, "maxLength": 5 }
      }
    }
  }
}
1 JSON 架构文档始终从其根目录描述整个文档。架构是架构对象本身,可以包含 描述属性和子文档的嵌入式架构对象。
2 required是一个属性,用于描述文档中需要哪些属性。可以选择性地指定它,以及其他 架构约束。请参阅 MongoDB 关于可用关键字的文档。
3 properties与描述类型的架构对象相关。它包含特定于属性的架构约束。object
4 firstname指定文档内字段的约束。在这里,它是一个基于字符串的元素声明 可能的字段值。firstnameproperties
5 address是一个子文档,用于定义其字段中值的架构。postCode

您可以通过指定架构文档(即使用 API 解析或构建文档对象)或使用 Spring Data 的 JSON 架构实用程序构建它来提供架构。 是所有 JSON 架构相关操作的入口点。以下示例演示如何使用 JSON 架构:Documentorg.springframework.data.mongodb.core.schemaMongoJsonSchemaMongoJsonSchema.builder()Spring中文文档

例 2.创建 JSON 架构
MongoJsonSchema.builder()                                                    (1)
    .required("lastname")                                                    (2)

    .properties(
                required(string("firstname").possibleValues("luke", "han")), (3)

                object("address")
                     .properties(string("postCode").minLength(4).maxLength(5)))

    .build();                                                                (4)
1 获取架构构建器,使用流畅的 API 配置架构。
2 直接配置所需属性,如下所示,或使用更多详细信息(如 3 所示)。
3 配置所需的 String 类型字段,仅允许 和 值。属性可以是类型化的,也可以是非类型的。使用 的静态导入可使语法稍微更紧凑,并获取入口点,例如 。firstnamelukehanJsonSchemaPropertystring(…)
4 生成架构对象。

已经有一些预定义的强类型架构对象( 和 ) 可用 通过网关接口上的静态方法。 但是,您可能需要生成自定义属性验证规则,这些规则可以通过构建器 API 创建,如以下示例所示:JsonSchemaObjectJsonSchemaPropertySpring中文文档

// "birthdate" : { "bsonType": "date" }
JsonSchemaProperty.named("birthdate").ofType(Type.dateType());

// "birthdate" : { "bsonType": "date", "description", "Must be a date" }
JsonSchemaProperty.named("birthdate").with(JsonSchemaObject.of(Type.dateType()).description("Must be a date"));

CollectionOptions提供对集合的架构支持的入口点,如以下示例所示:Spring中文文档

例 3.创建集合$jsonSchema
MongoJsonSchema schema = MongoJsonSchema.builder().required("firstname", "lastname").build();

template.createCollection(Person.class, CollectionOptions.empty().schema(schema));
1 JSON 架构文档始终从其根目录描述整个文档。架构是架构对象本身,可以包含 描述属性和子文档的嵌入式架构对象。
2 required是一个属性,用于描述文档中需要哪些属性。可以选择性地指定它,以及其他 架构约束。请参阅 MongoDB 关于可用关键字的文档。
3 properties与描述类型的架构对象相关。它包含特定于属性的架构约束。object
4 firstname指定文档内字段的约束。在这里,它是一个基于字符串的元素声明 可能的字段值。firstnameproperties
5 address是一个子文档,用于定义其字段中值的架构。postCode
1 获取架构构建器,使用流畅的 API 配置架构。
2 直接配置所需属性,如下所示,或使用更多详细信息(如 3 所示)。
3 配置所需的 String 类型字段,仅允许 和 值。属性可以是类型化的,也可以是非类型的。使用 的静态导入可使语法稍微更紧凑,并获取入口点,例如 。firstnamelukehanJsonSchemaPropertystring(…)
4 生成架构对象。

生成架构

设置架构可能是一项耗时的任务,我们鼓励每个决定这样做的人真正花时间。 这很重要,架构更改可能很困难。 然而,有时人们可能不想犹豫不决,这就是发挥作用的地方。JsonSchemaCreatorSpring中文文档

JsonSchemaCreator其默认实现生成由映射基础结构提供的域外类型元数据。 这意味着,要考虑带注释的属性以及潜在的自定义转换MongoJsonSchemaSpring中文文档

例 4.从域类型生成 Json 架构
public class Person {

    private final String firstname;                   (1)
    private final int age;                            (2)
    private Species species;                          (3)
    private Address address;                          (4)
    private @Field(fieldType=SCRIPT) String theForce; (5)
    private @Transient Boolean useTheForce;           (6)

    public Person(String firstname, int age) {        (1) (2)

        this.firstname = firstname;
        this.age = age;
    }

    // gettter / setter omitted
}

MongoJsonSchema schema = MongoJsonSchemaCreator.create(mongoOperations.getConverter())
    .createSchemaFor(Person.class);

template.createCollection(Person.class, CollectionOptions.empty().schema(schema));
{
    'type' : 'object',
    'required' : ['age'],                     (2)
    'properties' : {
        'firstname' : { 'type' : 'string' },  (1)
        'age' : { 'bsonType' : 'int' }        (2)
        'species' : {                         (3)
            'type' : 'string',
            'enum' : ['HUMAN', 'WOOKIE', 'UNKNOWN']
        }
        'address' : {                         (4)
            'type' : 'object'
            'properties' : {
                'postCode' : { 'type': 'string' }
            }
        },
        'theForce' : { 'type' : 'javascript'} (5)
     }
}
1 简单对象属性被视为常规属性。
2 基元类型被视为必需属性
3 枚举仅限于可能的值。
4 检查对象类型属性并将其表示为嵌套文档。
5 String由转换器转换为的 type 属性。Code
6 @Transient生成架构时将省略属性。
_id使用可转换为“喜欢”的类型的属性将映射到,除非通过注释提供更具体的信息。ObjectIdString{ type : 'object' }@MongoId
表 1.Sepcial Schema 生成规则
爪哇岛 架构类型 笔记

ObjectSpring中文文档

type : objectSpring中文文档

如果元数据可用。propertiesSpring中文文档

CollectionSpring中文文档

type : arraySpring中文文档

-Spring中文文档

MapSpring中文文档

type : objectSpring中文文档

-Spring中文文档

EnumSpring中文文档

type : stringSpring中文文档

属性包含可能的枚举值。enumSpring中文文档

arraySpring中文文档

type : arraySpring中文文档

简单类型数组,除非它是byte[]Spring中文文档

byte[]Spring中文文档

bsonType : binDataSpring中文文档

-Spring中文文档

上面的示例演示了如何从非常精确的类型化源派生架构。 在领域模型中使用多态元素可能会导致 和 泛型类型的架构表示不准确,这些类型很可能表示为没有进一步规范。 允许定义其他详细信息,例如呈现架构时应考虑的嵌套文档类型。Object<T>{ type : 'object' }MongoJsonSchemaCreator.property(…)Spring中文文档

例 5.为属性指定其他类型
class Root {
	Object value;
}

class A {
	String aValue;
}

class B {
	String bValue;
}
MongoJsonSchemaCreator.create()
    .property("value").withTypes(A.class, B.class) (1)
{
    'type' : 'object',
    'properties' : {
        'value' : {
            'type' : 'object',
            'properties' : {                       (1)
                'aValue' : { 'type' : 'string' },
                'bValue' : { 'type' : 'string' }
            }
        }
    }
}
1 给定类型的属性将合并到一个元素中。

MongoDB的无模式方法允许将不同结构的文档存储在一个集合中。 这些可以建模为具有公共基类。 无论选择哪种方法,都可以帮助规避将多个架构合并为一个架构的需要。MongoJsonSchemaCreator.merge(…)Spring中文文档

例 6.将多个架构合并到单个架构定义中
abstract class Root {
	String rootValue;
}

class A extends Root {
	String aValue;
}

class B extends Root {
	String bValue;
}

MongoJsonSchemaCreator.mergedSchemaFor(A.class, B.class) (1)
{
    'type' : 'object',
       'properties' : { (1)
           'rootValue' : { 'type' : 'string' },
           'aValue' : { 'type' : 'string' },
           'bValue' : { 'type' : 'string' }
       }
    }
}
1 给定类型的属性(及其继承的属性)将合并到一个架构中。

具有相同名称的属性需要引用相同的 JSON 架构才能合并。 下面的示例显示了由于数据类型不匹配而无法自动合并的定义。 在这种情况下,必须向 提供 。ConflictResolutionFunctionMongoJsonSchemaCreatorSpring中文文档

class A extends Root {
	String value;
}

class B extends Root {
	Integer value;
}
1 简单对象属性被视为常规属性。
2 基元类型被视为必需属性
3 枚举仅限于可能的值。
4 检查对象类型属性并将其表示为嵌套文档。
5 String由转换器转换为的 type 属性。Code
6 @Transient生成架构时将省略属性。
_id使用可转换为“喜欢”的类型的属性将映射到,除非通过注释提供更具体的信息。ObjectIdString{ type : 'object' }@MongoId
表 1.Sepcial Schema 生成规则
爪哇岛 架构类型 笔记

ObjectSpring中文文档

type : objectSpring中文文档

如果元数据可用。propertiesSpring中文文档

CollectionSpring中文文档

type : arraySpring中文文档

-Spring中文文档

MapSpring中文文档

type : objectSpring中文文档

-Spring中文文档

EnumSpring中文文档

type : stringSpring中文文档

属性包含可能的枚举值。enumSpring中文文档

arraySpring中文文档

type : arraySpring中文文档

简单类型数组,除非它是byte[]Spring中文文档

byte[]Spring中文文档

bsonType : binDataSpring中文文档

-Spring中文文档

1 给定类型的属性将合并到一个元素中。
1 给定类型的属性(及其继承的属性)将合并到一个架构中。

具有相同名称的属性需要引用相同的 JSON 架构才能合并。 下面的示例显示了由于数据类型不匹配而无法自动合并的定义。 在这种情况下,必须向 提供 。ConflictResolutionFunctionMongoJsonSchemaCreatorSpring中文文档

class A extends Root {
	String value;
}

class B extends Root {
	Integer value;
}

加密字段

MongoDB 4.2 字段级加密允许直接加密单个属性。Spring中文文档

设置 JSON 架构时,可以将属性包装在加密属性中,如以下示例所示。Spring中文文档

例 7.通过 Json 架构进行客户端字段级加密
MongoJsonSchema schema = MongoJsonSchema.builder()
    .properties(
        encrypted(string("ssn"))
            .algorithm("AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic")
            .keyId("*key0_id")
	).build();

与其手动定义加密字段,不如利用注释,如下面的代码片段所示。@EncryptedSpring中文文档

例 8.通过 Json 架构进行客户端字段级加密
@Document
@Encrypted(keyId = "xKVup8B1Q+CkHaVRx+qa+g==", algorithm = "AEAD_AES_256_CBC_HMAC_SHA_512-Random") (1)
static class Patient {

    @Id String id;
    String name;

    @Encrypted (2)
    String bloodType;

    @Encrypted(algorithm = "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic") (3)
    Integer ssn;
}
1 将为 设置的默认加密设置。encryptMetadata
2 使用默认加密设置的加密字段。
3 覆盖默认加密算法的加密字段。

注解支持通过 SpEL 表达式解析 keyId。 为此,需要提供额外的环境元数据(通过 )。@EncryptedMappingContextSpring中文文档

@Document
@Encrypted(keyId = "#{mongocrypt.keyId(#target)}")
static class Patient {

    @Id String id;
    String name;

    @Encrypted(algorithm = "AEAD_AES_256_CBC_HMAC_SHA_512-Random")
    String bloodType;

    @Encrypted(algorithm = "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic")
    Integer ssn;
}

MongoJsonSchemaCreator schemaCreator = MongoJsonSchemaCreator.create(mappingContext);
MongoJsonSchema patientSchema = schemaCreator
    .filter(MongoJsonSchemaCreator.encryptedOnly())
    .createSchemaFor(Patient.class);

该函数通过 an 定义,如下面的代码片段所示。 提供自定义扩展提供了计算 keyId 的最灵活方法。mongocrypt.keyIdEvaluationContextExtensionSpring中文文档

public class EncryptionExtension implements EvaluationContextExtension {

    @Override
    public String getExtensionId() {
        return "mongocrypt";
    }

    @Override
    public Map<String, Function> getFunctions() {
        return Collections.singletonMap("keyId", new Function(getMethod("computeKeyId", String.class), this));
    }

    public String computeKeyId(String target) {
        // ... lookup via target element name
    }
}
1 将为 设置的默认加密设置。encryptMetadata
2 使用默认加密设置的加密字段。
3 覆盖默认加密算法的加密字段。

注解支持通过 SpEL 表达式解析 keyId。 为此,需要提供额外的环境元数据(通过 )。@EncryptedMappingContextSpring中文文档

@Document
@Encrypted(keyId = "#{mongocrypt.keyId(#target)}")
static class Patient {

    @Id String id;
    String name;

    @Encrypted(algorithm = "AEAD_AES_256_CBC_HMAC_SHA_512-Random")
    String bloodType;

    @Encrypted(algorithm = "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic")
    Integer ssn;
}

MongoJsonSchemaCreator schemaCreator = MongoJsonSchemaCreator.create(mappingContext);
MongoJsonSchema patientSchema = schemaCreator
    .filter(MongoJsonSchemaCreator.encryptedOnly())
    .createSchemaFor(Patient.class);

该函数通过 an 定义,如下面的代码片段所示。 提供自定义扩展提供了计算 keyId 的最灵活方法。mongocrypt.keyIdEvaluationContextExtensionSpring中文文档

public class EncryptionExtension implements EvaluationContextExtension {

    @Override
    public String getExtensionId() {
        return "mongocrypt";
    }

    @Override
    public Map<String, Function> getFunctions() {
        return Collections.singletonMap("keyId", new Function(getMethod("computeKeyId", String.class), this));
    }

    public String computeKeyId(String target) {
        // ... lookup via target element name
    }
}

JSON 架构类型

下表显示了支持的 JSON 架构类型:Spring中文文档

表 2.支持的 JSON 架构类型
架构类型 Java 类型 架构属性

untypedSpring中文文档

-Spring中文文档

description生成descriptionenumallOfanyOfoneOfnotSpring中文文档

objectSpring中文文档

ObjectSpring中文文档

required, , , , ,additionalPropertiespropertiesminPropertiesmaxPropertiespatternPropertiesSpring中文文档

arraySpring中文文档

任何数组,除了byte[]Spring中文文档

uniqueItems, , , ,additionalItemsitemsminItemsmaxItemsSpring中文文档

stringSpring中文文档

StringSpring中文文档

minLength, ,maxLentgthpatternSpring中文文档

intSpring中文文档

int,IntegerSpring中文文档

multipleOf, , , ,minimumexclusiveMinimummaximumexclusiveMaximumSpring中文文档

longSpring中文文档

long,LongSpring中文文档

multipleOf, , , ,minimumexclusiveMinimummaximumexclusiveMaximumSpring中文文档

doubleSpring中文文档

float, , ,FloatdoubleDoubleSpring中文文档

multipleOf, , , ,minimumexclusiveMinimummaximumexclusiveMaximumSpring中文文档

decimalSpring中文文档

BigDecimalSpring中文文档

multipleOf, , , ,minimumexclusiveMinimummaximumexclusiveMaximumSpring中文文档

numberSpring中文文档

NumberSpring中文文档

multipleOf, , , ,minimumexclusiveMinimummaximumexclusiveMaximumSpring中文文档

binDataSpring中文文档

byte[]Spring中文文档

(无)Spring中文文档

booleanSpring中文文档

boolean,BooleanSpring中文文档

(无)Spring中文文档

nullSpring中文文档

nullSpring中文文档

(无)Spring中文文档

objectIdSpring中文文档

ObjectIdSpring中文文档

(无)Spring中文文档

dateSpring中文文档

java.util.DateSpring中文文档

(无)Spring中文文档

timestampSpring中文文档

BsonTimestampSpring中文文档

(无)Spring中文文档

regexSpring中文文档

java.util.regex.PatternSpring中文文档

(无)Spring中文文档

untyped是所有类型化架构类型继承的泛型类型。它为类型化的架构类型提供所有架构属性。untyped

有关详细信息,请参阅$jsonSchemaSpring中文文档

表 2.支持的 JSON 架构类型
架构类型 Java 类型 架构属性

untypedSpring中文文档

-Spring中文文档

description生成descriptionenumallOfanyOfoneOfnotSpring中文文档

objectSpring中文文档

ObjectSpring中文文档

required, , , , ,additionalPropertiespropertiesminPropertiesmaxPropertiespatternPropertiesSpring中文文档

arraySpring中文文档

任何数组,除了byte[]Spring中文文档

uniqueItems, , , ,additionalItemsitemsminItemsmaxItemsSpring中文文档

stringSpring中文文档

StringSpring中文文档

minLength, ,maxLentgthpatternSpring中文文档

intSpring中文文档

int,IntegerSpring中文文档

multipleOf, , , ,minimumexclusiveMinimummaximumexclusiveMaximumSpring中文文档

longSpring中文文档

long,LongSpring中文文档

multipleOf, , , ,minimumexclusiveMinimummaximumexclusiveMaximumSpring中文文档

doubleSpring中文文档

float, , ,FloatdoubleDoubleSpring中文文档

multipleOf, , , ,minimumexclusiveMinimummaximumexclusiveMaximumSpring中文文档

decimalSpring中文文档

BigDecimalSpring中文文档

multipleOf, , , ,minimumexclusiveMinimummaximumexclusiveMaximumSpring中文文档

numberSpring中文文档

NumberSpring中文文档

multipleOf, , , ,minimumexclusiveMinimummaximumexclusiveMaximumSpring中文文档

binDataSpring中文文档

byte[]Spring中文文档

(无)Spring中文文档

booleanSpring中文文档

boolean,BooleanSpring中文文档

(无)Spring中文文档

nullSpring中文文档

nullSpring中文文档

(无)Spring中文文档

objectIdSpring中文文档

ObjectIdSpring中文文档

(无)Spring中文文档

dateSpring中文文档

java.util.DateSpring中文文档

(无)Spring中文文档

timestampSpring中文文档

BsonTimestampSpring中文文档

(无)Spring中文文档

regexSpring中文文档

java.util.regex.PatternSpring中文文档

(无)Spring中文文档

untyped是所有类型化架构类型继承的泛型类型。它为类型化的架构类型提供所有架构属性。untyped