Overview
This guide shows you how to create a Queryable Encryption-enabled collection and insert a document with encrypted fields.
After you complete the steps in this guide, you should be able to create an encrypted collection and insert a document with fields that are encrypted with your Customer Master Key.
Before You Start
Create your Queryable Encryption-enabled application before creating an encrypted collection.
If you are using explicit encryption, you must also create a unique Data Encryption Key for each encrypted field in advance. For more information, see Encryption Keys and Key Vaults.
Procedure
Specify fields to encrypt.
To encrypt a field, add it to the encryption schema. To enable queries on a field, add the queries property. You can enable fields to be queryable by the following types of queries:
Equality
Range
Prefix, suffix, or substring
The following steps demonstrate how to specify fields to encrypt with each query type.
Specify fields for equality queries.
To enable equality queries on a field, add the field to the encryption schema with a
queryTypeof"equality". The following code sample encrypts both thessnandbillingfields, but only thessnfield is queryable:const collectionOpts = { encryptedFields: { fields: [ { path: "patientRecord.ssn", bsonType: "string", queries: { queryType: "equality" }, }, { path: "patientRecord.billing", bsonType: "object", }, ], }, }; Specify fields for range queries.
To enable range queries on a field, add the field to the encryption schema with a
queryTypeof"range". The following example adds thebillAmountfield to the encryption schema created in the preceding step and enables range queries on it:const collectionOpts = { encryptedFields: { fields: [ { path: "patientRecord.ssn", bsonType: "string", queries: { queryType: "equality" }, }, { path: "patientRecord.billing", bsonType: "object", }, { path: "patientRecord.billAmount", bsonType: "int", queries: { queryType: "range", sparsity: 1, trimFactor: 4, min: 100, max: 2000, }, }, ], }, }; Specify fields for prefix, suffix, or substring queries.
Note
MongoDB Shell does not currently support prefix, suffix, or substring queries on encrypted fields.
For extended versions of these steps, see Create an Encryption Schema.
Create the collection.
Important
Explicitly create your collection, rather than creating it implicitly with an insert operation. When you create a collection using createCollection(), MongoDB creates an index on the encrypted fields. Without this index, queries on encrypted fields may run slowly.
Create your encrypted collection by using the encryption helper method accessed through the ClientEncryption class. This method automatically generates data encryption keys for your encrypted fields and creates the encrypted collection:
await clientEncryption.createEncryptedCollection( encryptedDatabaseName, encryptedCollectionName, { provider: kmsProviderName, createCollectionOptions: collectionOpts, masterKey: customerMasterKeyCredentials, } );
For additional information, see Enable Queryable Encryption when Creating a Collection.
Insert a document with encrypted fields.
Create a sample document that describes a patient's personal information. Use the encrypted client to insert it into the patients collection, as shown in the following example:
const patientDocument = { patientName: "Jon Doe", patientId: 12345678, patientRecord: { ssn: "987-65-4320", billing: { type: "Visa", number: "4111111111111111", }, billAmount: 1500, }, }; const encryptedCollection = encryptedClient .getDB(encryptedDatabaseName) .getCollection(encryptedCollectionName); const insertResult = await encryptedCollection.insertOne(patientDocument);
Specify fields to encrypt.
To encrypt a field, add it to the encryption schema. To enable queries on a field, add the queries property. You can enable fields to be queryable by the following types of queries:
Equality
Range
Prefix, suffix, or substring
The following steps demonstrate how to specify fields to encrypt with each query type.
Specify fields for equality queries.
To enable equality queries on a field, add the field to the encryption schema with a
queryTypeof"equality". The following code sample encrypts both thessnandbillingfields, but only thessnfield is queryable:const collectionOpts = { encryptedFields: { fields: [ { path: "patientRecord.ssn", bsonType: "string", queries: { queryType: "equality" }, }, { path: "patientRecord.billing", bsonType: "object", }, ], }, }; Specify fields for range queries.
To enable range queries on a field, add the field to the encryption schema with a
queryTypeof"range". The following example adds thebillAmountfield to the encryption schema created in the preceding step and enables range queries on it:const collectionOpts = { encryptedFields: { fields: [ { path: "patientRecord.ssn", bsonType: "string", queries: { queryType: "equality" }, }, { path: "patientRecord.billing", bsonType: "object", }, { path: "patientRecord.billAmount", bsonType: "int", queries: { queryType: "range", sparsity: 1, trimFactor: 4, min: 100, max: 2000, }, }, ], }, }; Specify fields for prefix, suffix, or substring queries.
To enable prefix, suffix, or substring queries on a field, add the field to the encryption schema with a
queryTypeof"prefix","suffix", or"substring"and the associated options. The following example enables prefix queries on thepatientRecord.ssnfield:const collectionOpts = { encryptedFields: { fields: [ { keyId: dek, path: "patientRecord.ssn", bsonType: "string", queries: { queryType: "prefix", strMinQueryLength: 3, strMaxQueryLength: 10, caseSensitive: true, diacriticSensitive: true, }, }, ], }, }; Tip
Suffix Query
To enable suffix queries on a field, change the
queryTypeoption to"suffix"in the preceding code example.The following example enables substring queries on the
patientRecord.ssnfield:const collectionOpts = { encryptedFields: { fields: [ { keyId: dek, path: "patientRecord.ssn", bsonType: "string", queries: { queryType: "substring", strMaxLength: 12, strMinQueryLength: 3, strMaxQueryLength: 6, caseSensitive: true, diacriticSensitive: true, }, }, ], }, };
For extended versions of these steps, see Create an Encryption Schema.
Create the collection.
Important
Explicitly create your collection, rather than creating it implicitly with an insert operation. When you create a collection using createCollection(), MongoDB creates an index on the encrypted fields. Without this index, queries on encrypted fields may run slowly.
Note
Import ClientEncryption
When using the Node.js driver v6.0 and later, you must import ClientEncryption from mongodb.
For earlier driver versions, import ClientEncryption from mongodb-client-encryption.
Create your encrypted collection by using the encryption helper method accessed through the ClientEncryption class. This method automatically generates data encryption keys for your encrypted fields and creates the encrypted collection:
await clientEncryption.createEncryptedCollection( encryptedDatabase, encryptedCollectionName, { provider: kmsProviderName, createCollectionOptions: collectionOpts, masterKey: customerMasterKeyCredentials, } );
Tip
Database vs. Database Name
The method that creates the encrypted collection requires a reference to a database object rather than the database name.
For additional information, see Enable Queryable Encryption when Creating a Collection.
Insert a document with encrypted fields.
Create a sample document that describes a patient's personal information. Use the encrypted client to insert it into the patients collection, as shown in the following example:
const patientDocument = { patientName: "Jon Doe", patientId: 12345678, patientRecord: { ssn: "987-65-4320", billing: { type: "Visa", number: "4111111111111111", }, billAmount: 1500, }, }; const encryptedCollection = encryptedClient .db(encryptedDatabaseName) .collection(encryptedCollectionName); const result = await encryptedCollection.insertOne(patientDocument);
Specify fields to encrypt.
To encrypt a field, add it to the encryption schema. To enable queries on a field, add the queries property. You can enable fields to be queryable by the following types of queries:
Equality
Range
Prefix, suffix, or substring
The following steps demonstrate how to specify fields to encrypt with each query type.
Specify fields for equality queries.
To enable equality queries on a field, add the field to the encryption schema with a
queryTypeof"equality". The following code sample encrypts both thessnandbillingfields, but only thessnfield is queryable:encrypted_fields = { "fields": [ { "path": "patientRecord.ssn", "bsonType": "string", "queries": [{"queryType": "equality"}] }, { "path": "patientRecord.billing", "bsonType": "object", } ] } Specify fields for range queries.
To enable range queries on a field, add the field to the encryption schema with a
queryTypeof"range". The following example adds thebillAmountfield to the encryption schema created in the preceding step and enables range queries on it:encrypted_fields = { "fields": [ { "path": "patientRecord.ssn", "bsonType": "string", "queries": [{"queryType": "equality"}] }, { "path": "patientRecord.billing", "bsonType": "object", }, { "path": "patientRecord.billAmount", "bsonType": "int", "queries": [{ "queryType": "range", "sparsity": 1, "min": 100, "max": 2000, "trimFactor": 4 }], }, ] } Specify fields for prefix, suffix, or substring queries.
To enable prefix, suffix, or substring queries on a field, add the field to the encryption schema with a
queryTypeof"prefix","suffix", or"substring"and the associated options. The following example enables prefix queries on thepatientRecord.ssnfield:encrypted_fields = { "fields": [ { "path": "patientRecord.ssn", "bsonType": "string", "queries": [{ "queryType": "prefix", "strMinQueryLength": 3, "strMaxQueryLength": 10, "caseSensitive": True, "diacriticSensitive": True, }] }, ] } Tip
Suffix Query
To enable suffix queries on a field, change the
queryTypeoption to"suffix"in the preceding code example.The following example enables substring queries on the
patientRecord.ssnfield:encrypted_fields = { "fields": [ { "path": "patientRecord.ssn", "bsonType": "string", "queries": [{ "queryType": "substring", "strMaxLength": 12, "strMinQueryLength": 3, "strMaxQueryLength": 6, "caseSensitive": True, "diacriticSensitive": True, }] }, ] }
For extended versions of these steps, see Create an Encryption Schema.
Instantiate a client encryption object to access the API for the encryption helper methods.
client_encryption = ClientEncryption( kms_providers=kms_provider_credentials, key_vault_namespace=key_vault_namespace, key_vault_client=encrypted_client, codec_options=CodecOptions(uuid_representation=STANDARD) )
Create the collection.
Important
Explicitly create your collection, rather than creating it implicitly with an insert operation. When you create a collection using createCollection(), MongoDB creates an index on the encrypted fields. Without this index, queries on encrypted fields may run slowly.
Create your encrypted collection by using the encryption helper method accessed through the ClientEncryption class. This method automatically generates data encryption keys for your encrypted fields and creates the encrypted collection:
client_encryption.create_encrypted_collection( encrypted_client[encrypted_database_name], encrypted_collection_name, encrypted_fields, kms_provider_name, customer_master_key_credentials, )
Tip
Database vs. Database Name
The method that creates the encrypted collection requires a reference to a database object rather than the database name. You can obtain this reference by using a method on your client object.
For additional information, see Enable Queryable Encryption when Creating a Collection.
Insert a document with encrypted fields.
Create a sample document that describes a patient's personal information. Use the encrypted client to insert it into the patients collection, as shown in the following example:
patient_document = { "patientName": "Jon Doe", "patientId": 12345678, "patientRecord": { "ssn": "987-65-4320", "billing": { "type": "Visa", "number": "4111111111111111", }, "billAmount": 1500, }, } encrypted_collection = encrypted_client[encrypted_database_name][encrypted_collection_name] result = encrypted_collection.insert_one(patient_document)
Specify fields to encrypt.
To encrypt a field, add it to the encryption schema. To enable queries on a field, add the queries property. You can enable fields to be queryable by the following types of queries:
Equality
Range
Prefix, suffix, or substring
The following steps demonstrate how to specify fields to encrypt with each query type.
Specify fields for equality queries.
To enable equality queries on a field, add the field to the encryption schema with a
queryTypeof"equality". The following code sample encrypts both thessnandbillingfields, but only thessnfield is queryable:BsonDocument encryptedFields = new BsonDocument().append("fields", new BsonArray(Arrays.asList( new BsonDocument() .append("keyId", new BsonNull()) .append("path", new BsonString("patientRecord.ssn")) .append("bsonType", new BsonString("string")) .append("queries", new BsonDocument() .append("queryType", new BsonString("equality"))), new BsonDocument() .append("keyId", new BsonNull()) .append("path", new BsonString("patientRecord.billing")) .append("bsonType", new BsonString("object"))))); Specify fields for range queries.
To enable range queries on a field, add the field to the encryption schema with a
queryTypeof"range". The following example adds thebillAmountfield to the encryption schema created in the preceding step and enables range queries on it:BsonDocument encryptedFields = new BsonDocument().append("fields", new BsonArray(Arrays.asList( new BsonDocument() .append("keyId", new BsonNull()) .append("path", new BsonString("patientRecord.ssn")) .append("bsonType", new BsonString("string")) .append("queries", new BsonDocument() .append("queryType", new BsonString("equality"))), new BsonDocument() .append("keyId", new BsonNull()) .append("path", new BsonString("patientRecord.billing")) .append("bsonType", new BsonString("object")), new BsonDocument() .append("keyId", new BsonNull()) .append("path", new BsonString("patientRecord.billAmount")) .append("bsonType", new BsonString("int")) .append("queries", new BsonDocument() .append("queryType", new BsonString("range")) .append("sparsity", new BsonInt32(1)) .append("trimFactor", new BsonInt32(4)) .append("min", new BsonInt32(100)) .append("max", new BsonInt32(2000)) )))); Specify fields for prefix, suffix, or substring queries.
To enable prefix, suffix, or substring queries on a field, add the field to the encryption schema with a
queryTypeof"prefix","suffix", or"substring"and the associated options. The following example enables prefix queries on thepatientRecord.ssnfield:BsonDocument encryptedFields = new BsonDocument().append("fields", new BsonArray(Arrays.asList( new BsonDocument() .append("keyId", new BsonNull()) .append("path", new BsonString("patientRecord.ssn")) .append("bsonType", new BsonString("string")) .append("queries", new BsonDocument() .append("queryType", new BsonString("prefix")) .append("strMinQueryLength", new BsonInt32(3)) .append("strMaxQueryLength", new BsonInt32(10)) .append("caseSensitive", new BsonBoolean(true)) .append("diacriticSensitive", new BsonBoolean(true)))))); Tip
Suffix Query
To enable suffix queries on a field, change the
queryTypeoption to"suffix"in the preceding code example.The following example enables substring queries on the
patientRecord.ssnfield:BsonDocument encryptedFields = new BsonDocument().append("fields", new BsonArray(Arrays.asList( new BsonDocument() .append("keyId", new BsonNull()) .append("path", new BsonString("patientRecord.ssn")) .append("bsonType", new BsonString("string")) .append("queries", new BsonDocument() .append("queryType", new BsonString("substring")) .append("strMaxLength", new BsonInt32(12)) .append("strMinQueryLength", new BsonInt32(3)) .append("strMaxQueryLength", new BsonInt32(6)) .append("caseSensitive", new BsonBoolean(true)) .append("diacriticSensitive", new BsonBoolean(true))))));
For extended versions of these steps, see Create an Encryption Schema.
Instantiate a client encryption object to access the API for the encryption helper methods.
ClientEncryptionSettings clientEncryptionSettings = ClientEncryptionSettings.builder() .keyVaultMongoClientSettings(MongoClientSettings.builder() .applyConnectionString(new ConnectionString(uri)) .build()) .keyVaultNamespace(keyVaultNamespace) .kmsProviders(kmsProviderCredentials) .build(); ClientEncryption clientEncryption = ClientEncryptions.create(clientEncryptionSettings);
Create the collection.
Important
Explicitly create your collection, rather than creating it implicitly with an insert operation. When you create a collection using createCollection(), MongoDB creates an index on the encrypted fields. Without this index, queries on encrypted fields may run slowly.
Create your encrypted collection by using the encryption helper method accessed through the ClientEncryption class. This method automatically generates data encryption keys for your encrypted fields and creates the encrypted collection:
CreateCollectionOptions createCollectionOptions = new CreateCollectionOptions().encryptedFields(encryptedFields); CreateEncryptedCollectionParams encryptedCollectionParams = new CreateEncryptedCollectionParams(kmsProviderName); encryptedCollectionParams.masterKey(customerMasterKeyCredentials); try { clientEncryption.createEncryptedCollection( encryptedClient.getDatabase(encryptedDatabaseName), encryptedCollectionName, createCollectionOptions, encryptedCollectionParams); } catch (Exception e) { throw new Exception("Unable to create encrypted collection due to the following error: " + e.getMessage()); }
Tip
Database vs. Database Name
The method that creates the encrypted collection requires a reference to a database object rather than the database name. You can obtain this reference by using a method on your client object.
For additional information, see Enable Queryable Encryption when Creating a Collection.
Insert a document with encrypted fields.
This tutorial uses POJOs as data models to represent the document structure. To set up your application to use POJOs, add the following code:
CodecProvider pojoCodecProvider = PojoCodecProvider.builder().automatic(true).build(); CodecRegistry pojoCodecRegistry = fromRegistries(getDefaultCodecRegistry(), fromProviders(pojoCodecProvider));
To learn more about Java POJOs, see the Plain Old Java Object wikipedia article.
This tutorial uses the following POJOs:
PatientPatientRecordPatientBilling
You can view these classes in the models package of the complete Java application.
Add these POJO classes to your application. Then, create an instance of a Patient that describes a patient's personal information. Use the encrypted client to insert it into the patients collection, as shown in the following example:
MongoDatabase encryptedDb = encryptedClient.getDatabase(encryptedDatabaseName).withCodecRegistry(pojoCodecRegistry); MongoCollection<Patient> collection = encryptedDb.getCollection(encryptedCollectionName, Patient.class); PatientBilling patientBilling = new PatientBilling("Visa", "4111111111111111"); PatientRecord patientRecord = new PatientRecord("987-65-4320", patientBilling, 1500); Patient patientDocument = new Patient("Jon Doe", patientRecord); InsertOneResult result = collection.insertOne(patientDocument);
Specify fields to encrypt.
To encrypt a field, add it to the encryption schema. To enable queries on a field, add the queries property. You can enable fields to be queryable by the following types of queries:
Equality
Range
Prefix, suffix, or substring
The following steps demonstrate how to specify fields to encrypt with each query type.
Specify fields for equality queries.
To enable equality queries on a field, add the field to the encryption schema with a
queryTypeof"equality". The following code sample encrypts both thessnandbillingfields, but only thessnfield is queryable:encryptedFields := bson.M{ "fields": []bson.M{ bson.M{ "keyId": nil, "path": "patientRecord.ssn", "bsonType": "string", "queries": []bson.M{ { "queryType": "equality", }, }, }, bson.M{ "keyId": nil, "path": "patientRecord.billing", "bsonType": "object", }, }, } Specify fields for range queries.
To enable range queries on a field, add the field to the encryption schema with a
queryTypeof"range". The following example adds thebillAmountfield to the encryption schema created in the preceding step and enables range queries on it:encryptedFields := bson.M{ "fields": []bson.M{ bson.M{ "keyId": nil, "path": "patientRecord.ssn", "bsonType": "string", "queries": []bson.M{ { "queryType": "equality", }, }, }, bson.M{ "keyId": nil, "path": "patientRecord.billing", "bsonType": "object", }, bson.M{ "keyId": nil, "path": "patientRecord.billAmount", "bsonType": "int", "queries": []bson.M{ { "queryType": "range", "sparsity": 1, "min": 100, "max": 2000, "trimFactor": 4, }, }, }, }, } Specify fields for prefix, suffix, or substring queries.
To enable prefix, suffix, or substring queries on a field, add the field to the encryption schema with a
queryTypeof"prefix","suffix", or"substring"and the associated options. The following example enables prefix queries on thepatientRecord.ssnfield:encryptedFields := bson.M{ "fields": []bson.M{ bson.M{ "keyId": nil, "path": "patientRecord.ssn", "bsonType": "string", "queries": []bson.M{ { "queryType": "prefix", "strMinQueryLength": 3, "strMaxQueryLength": 10, "caseSensitive": true, "diacriticSensitive": true, }, }, }, }, } Tip
Suffix Query
To enable suffix queries on a field, change the
queryTypeoption to"suffix"in the preceding code example.The following example enables substring queries on the
patientRecord.ssnfield:encryptedFields := bson.M{ "fields": []bson.M{ bson.M{ "keyId": nil, "path": "patientRecord.ssn", "bsonType": "string", "queries": []bson.M{ { "queryType": "substring", "strMaxLength": 12, "strMinQueryLength": 3, "strMaxQueryLength": 6, "caseSensitive": true, "diacriticSensitive": true, }, }, }, }, }
For extended versions of these steps, see Create an Encryption Schema.
Instantiate a client encryption object to access the API for the encryption helper methods.
clientEncryptionOpts := options.ClientEncryption(). SetKeyVaultNamespace(keyVaultNamespace). SetKmsProviders(kmsProviderCredentials) clientEncryption, err := mongo.NewClientEncryption(encryptedClient, clientEncryptionOpts) if err != nil { panic(fmt.Sprintf("Unable to create a ClientEncryption instance due to the following error: %s\n", err)) }
Create the collection.
Important
Explicitly create your collection, rather than creating it implicitly with an insert operation. When you create a collection using createCollection(), MongoDB creates an index on the encrypted fields. Without this index, queries on encrypted fields may run slowly.
The Golang version of this tutorial uses data models to represent the document structure. Add the following structs to your project to represent the data in your collection:
type PatientDocument struct { PatientName string `bson:"patientName"` PatientID int32 `bson:"patientId"` PatientRecord PatientRecord `bson:"patientRecord"` }
type PatientRecord struct { SSN string `bson:"ssn"` Billing PaymentInfo `bson:"billing"` BillAmount int `bson:"billAmount"` }
type PaymentInfo struct { Type string `bson:"type"` Number string `bson:"number"` }
After you've added these classes, create your encrypted collection by using the encryption helper method accessed through the ClientEncryption class. This method automatically generates data encryption keys for your encrypted fields and creates the encrypted collection:
createCollectionOptions := options.CreateCollection().SetEncryptedFields(encryptedFields) _, _, err = clientEncryption.CreateEncryptedCollection( context.TODO(), encryptedClient.Database(encryptedDatabaseName), encryptedCollectionName, createCollectionOptions, kmsProviderName, customerMasterKey, )
Tip
Database vs. Database Name
The method that creates the encrypted collection requires a reference to a database object rather than the database name. You can obtain this reference by using a method on your client object.
For additional information, see Enable Queryable Encryption when Creating a Collection.
Insert a document with encrypted fields.
Create a sample document that describes a patient's personal information. Use the encrypted client to insert it into the patients collection, as shown in the following example:
patientDocument := &PatientDocument{ PatientName: "Jon Doe", PatientID: 12345678, PatientRecord: PatientRecord{ SSN: "987-65-4320", Billing: PaymentInfo{ Type: "Visa", Number: "4111111111111111", }, BillAmount: 1500, }, } coll := encryptedClient.Database(encryptedDatabaseName).Collection(encryptedCollectionName) _, err = coll.InsertOne(context.TODO(), patientDocument) if err != nil { panic(fmt.Sprintf("Unable to insert the patientDocument: %s", err)) }
Specify fields to encrypt.
To encrypt a field, add it to the encryption schema. To enable queries on a field, add the queries property. You can enable fields to be queryable by the following types of queries:
Equality
Range
Prefix, suffix, or substring
The following steps demonstrate how to specify fields to encrypt with each query type.
Specify fields for equality queries.
To enable equality queries on a field, add the field to the encryption schema with a
queryTypeof"equality". The following code sample encrypts both thessnandbillingfields, but only thessnfield is queryable:var encryptedFields = new BsonDocument { { "fields", new BsonArray { new BsonDocument { { "keyId", BsonNull.Value }, { "path", "patientRecord.ssn" }, { "bsonType", "string" }, { "queries", new BsonDocument("queryType", "equality") } }, new BsonDocument { { "keyId", BsonNull.Value }, { "path", "patientRecord.billing" }, { "bsonType", "object" } } } } }; Specify fields for range queries.
To enable range queries on a field, add the field to the encryption schema with a
queryTypeof"range". The following example adds thebillAmountfield to the encryption schema created in the preceding step and enables range queries on it:var encryptedFields = new BsonDocument { { "fields", new BsonArray { new BsonDocument { { "keyId", BsonNull.Value }, { "path", "patientRecord.ssn" }, { "bsonType", "string" }, { "queries", new BsonDocument("queryType", "equality") } }, new BsonDocument { { "keyId", BsonNull.Value }, { "path", "patientRecord.billing" }, { "bsonType", "object" } }, new BsonDocument { { "keyId", BsonNull.Value }, { "path", "patientRecord.billAmount" }, { "bsonType", "int" }, { "queries", new BsonDocument { { "queryType", "range" }, { "sparsity", 1 }, { "min", 100 }, { "max", 2000 }, { "trimFactor", 4 } } }, } } } }; Specify fields for prefix, suffix, or substring queries.
To enable prefix, suffix, or substring queries on a field, add the field to the encryption schema with a
queryTypeof"prefix","suffix", or"substring"and the associated options. The following example enables prefix queries on thepatientRecord.ssnfield:var encryptedFields = new BsonDocument { { "fields", new BsonArray { new BsonDocument { { "keyId", BsonNull.Value }, { "path", "patientRecord.ssn" }, { "bsonType", "string" }, { "queries", new BsonDocument { { "queryType", "prefix" }, { "strMinQueryLength", 3 }, { "strMaxQueryLength", 10 }, { "caseSensitive", true }, { "diacriticSensitive", true } } } } } } }; Tip
Suffix Query
To enable suffix queries on a field, change the
queryTypeoption to"suffix"in the preceding code example.The following example enables substring queries on the
patientRecord.ssnfield:var encryptedFields = new BsonDocument { { "fields", new BsonArray { new BsonDocument { { "keyId", BsonNull.Value }, { "path", "patientRecord.ssn" }, { "bsonType", "string" }, { "queries", new BsonDocument { { "queryType", "substring" }, { "strMaxLength", 12 }, { "strMinQueryLength", 3 }, { "strMaxQueryLength", 6 }, { "caseSensitive", true }, { "diacriticSensitive", true } } } } } } };
For extended versions of these steps, see Create an Encryption Schema.
Instantiate a client encryption object to access the API for the encryption helper methods.
var clientEncryptionOptions = new ClientEncryptionOptions( keyVaultClient: keyVaultClient, keyVaultNamespace: keyVaultNamespace, kmsProviders: kmsProviderCredentials ); var clientEncryption = new ClientEncryption(clientEncryptionOptions);
Create the collection.
Important
Explicitly create your collection, rather than creating it implicitly with an insert operation. When you create a collection using createCollection(), MongoDB creates an index on the encrypted fields. Without this index, queries on encrypted fields may run slowly.
The C# version of this tutorial uses separate classes as data models to represent the document structure. Add the following Patient, PatientRecord, and PatientBilling classes to your project:
using MongoDB.Bson; using MongoDB.Bson.Serialization.Attributes; [] public class Patient { public ObjectId Id { get; set; } public string PatientName { get; set; } public PatientRecord PatientRecord { get; set; } }
public class PatientRecord { public string Ssn { get; set; } public PatientBilling Billing { get; set; } public int BillAmount { get; set; } }
public class PatientBilling { public string CardType { get; set; } public long CardNumber { get; set; } }
After you've added these classes, create your encrypted collection by using the encryption helper method accessed through the ClientEncryption class. This method automatically generates data encryption keys for your encrypted fields and creates the encrypted collection:
var patientDatabase = encryptedClient.GetDatabase(encryptedDatabaseName); patientDatabase.DropCollection(encryptedCollectionName); // Ensure the collection is dropped before creating a new one try { var createCollectionOptions = new CreateCollectionOptions<Patient> { EncryptedFields = encryptedFields }; clientEncryption.CreateEncryptedCollection(patientDatabase, encryptedCollectionName, createCollectionOptions, kmsProviderName, customerMasterKeyCredentials); } catch (Exception e) { throw new Exception("Unable to create encrypted collection due to the following error: " + e.Message); }
Tip
Database vs. Database Name
The method that creates the collection requires a reference to a database object rather than the database name.
For additional information, see Enable Queryable Encryption when Creating a Collection.
Insert a document with encrypted fields.
Create a sample document that describes a patient's personal information. Use the encrypted client to insert it into the patients collection, as shown in the following example:
var patient = new Patient { PatientName = "Jon Doe", Id = new ObjectId(), PatientRecord = new PatientRecord { Ssn = "987-65-4320", Billing = new PatientBilling { CardType = "Visa", CardNumber = 4111111111111111, }, BillAmount = 1500 } }; var encryptedCollection = encryptedClient.GetDatabase(encryptedDatabaseName). GetCollection<Patient>(encryptedCollectionName); await encryptedCollection.InsertOneAsync(patient);
Specify fields to encrypt.
To encrypt a field, add it to the encryption schema. To enable queries on a field, add the queries property. You can enable fields to be queryable by the following types of queries:
Equality
Range
Prefix, suffix, or substring
The following steps demonstrate how to specify fields to encrypt with each query type.
Specify fields for equality queries.
To enable equality queries on a field, add the field to the encryption schema with a
queryTypeof"equality". The following code sample encrypts both thessnandbillingfields, but only thessnfield is queryable:let encrypted_fields = doc! { "fields": [ { "path": "patientRecord.ssn", "bsonType": "string", "keyId": Bson::Null, "queries": { "queryType": "equality" }, }, { "path": "patientRecord.billing", "bsonType": "object", "keyId": Bson::Null, }, ] }; Specify fields for range queries.
To enable range queries on a field, add the field to the encryption schema with a
queryTypeof"range". The following example adds thebillAmountfield to the encryption schema created in the preceding step and enables range queries on it:let encrypted_fields = doc! { "fields": [ { "path": "patientRecord.ssn", "bsonType": "string", "keyId": Bson::Null, "queries": { "queryType": "equality" }, }, { "path": "patientRecord.billing", "bsonType": "object", "keyId": Bson::Null, }, { "path": "patientRecord.billAmount", "bsonType": "int", "queries": { "queryType": "range", "sparsity": 1, "min": 100, "max": 2000, "trimFactor": 4 }, }, ] }; Specify fields for prefix, suffix, or substring queries.
To enable prefix, suffix, or substring queries on a field, add the field to the encryption schema with a
queryTypeof"prefix","suffix", or"substring"and the associated options. The following example enables prefix queries on thepatientRecord.ssnfield:let encrypted_fields = doc! { "fields": [ { "path": "patientRecord.ssn", "bsonType": "string", "keyId": Bson::Null, "queries": { "queryType": "prefix", "strMinQueryLength": 3, "strMaxQueryLength": 10, "caseSensitive": true, "diacriticSensitive": true }, }, ] }; Tip
Suffix Query
To enable suffix queries on a field, change the
queryTypeoption to"suffix"in the preceding code example.The following example enables substring queries on the
patientRecord.ssnfield:let encrypted_fields = doc! { "fields": [ { "path": "patientRecord.ssn", "bsonType": "string", "keyId": Bson::Null, "queries": { "queryType": "substring", "strMaxLength": 12, "strMinQueryLength": 3, "strMaxQueryLength": 6, "caseSensitive": true, "diacriticSensitive": true }, }, ] };
For extended versions of these steps, see Create an Encryption Schema.
Instantiate a client encryption object to access the API for the encryption helper methods.
let encrypted_client = encrypted_client_builder .extra_options(Some(doc!{ "cryptSharedLibPath": env::var("SHARED_LIB_PATH").expect("Set SHARED_LIB_PATH environment variable to path to crypt_shared library") })) .key_vault_client(Client::with_uri_str(uri).await.unwrap()) .build() .await .unwrap();
Create the collection.
Important
Explicitly create your collection, rather than creating it implicitly with an insert operation. When you create a collection using createCollection(), MongoDB creates an index on the encrypted fields. Without this index, queries on encrypted fields may run slowly.
Create your encrypted collection by using the encryption helper method accessed through the ClientEncryption class. This method automatically generates data encryption keys for your encrypted fields and creates the encrypted collection:
client_encryption.create_encrypted_collection( &encrypted_client.database(encrypted_database_name), encrypted_collection_name, customer_master_key_credentials ) .encrypted_fields(encrypted_fields) .await .1?;
Tip
Database vs. Database Name
The method that creates the encrypted collection requires a reference to a database object rather than the database name. You can obtain this reference by using the database() method on your client object.
For additional information, see Enable Queryable Encryption when Creating a Collection.
Insert a document with encrypted fields.
Create a sample document that describes a patient's personal information. Use the encrypted client to insert it into the patients collection, as shown in the following example:
let patient_document = doc! { "patientName": "Jon Doe", "patientId": 12345678, "patientRecord": { "ssn": "987-65-4320", "billing": { "type": "Visa", "number": "4111111111111111", }, "billAmount": 1500, } }; let encrypted_coll: Collection<Document> = encrypted_client .database(encrypted_database_name) .collection(encrypted_collection_name); let insert_result = encrypted_coll.insert_one(patient_document).await?;
Specify fields to encrypt.
To encrypt a field, add it to the encryption schema. To enable queries on a field, add the queries property. You can enable fields to be queryable by the following types of queries:
Equality
Range
Prefix, suffix, or substring
The following steps demonstrate how to specify fields to encrypt with each query type.
Specify fields for equality queries.
To enable equality queries on a field, add the field to the encryption schema with a
queryTypeof"equality". The following code sample encrypts both thessnandbillingfields, but only thessnfield is queryable:auto const encrypted_fields = make_document(kvp("fields", bsoncxx::builder::basic::make_array( make_document( kvp("path", "patientRecord.ssn"), kvp("bsonType", "string"), kvp("keyId", bsoncxx::types::b_null{}), kvp("queries", make_document(kvp("queryType", "equality")))), make_document( kvp("path", "patientRecord.billing"), kvp("bsonType", "object"), kvp("keyId", bsoncxx::types::b_null{}))))); Specify fields for range queries.
To enable range queries on a field, add the field to the encryption schema with a
queryTypeof"range". The following example adds thebillAmountfield to the encryption schema created in the preceding step and enables range queries on it:auto const encrypted_fields = make_document(kvp("fields", bsoncxx::builder::basic::make_array( make_document( kvp("path", "patientRecord.ssn"), kvp("bsonType", "string"), kvp("keyId", bsoncxx::types::b_null{}), kvp("queries", make_document(kvp("queryType", "equality")))), make_document( kvp("path", "patientRecord.billing"), kvp("bsonType", "object"), kvp("keyId", bsoncxx::types::b_null{})), make_document( kvp("path", "patientRecord.billAmount"), kvp("bsonType", "int"), kvp("keyId", bsoncxx::types::b_null{}), kvp("queries", make_document( kvp("queryType", "range"), kvp("sparsity", 1), kvp("min", 100), kvp("max", 2000), kvp("trimFactor", 4))))))); Specify fields for prefix, suffix, or substring queries.
To enable prefix, suffix, or substring queries on a field, add the field to the encryption schema with a
queryTypeof"prefix","suffix", or"substring"and the associated options. The following example enables prefix queries on thepatientRecord.ssnfield:auto const encrypted_fields = make_document(kvp("fields", bsoncxx::builder::basic::make_array( make_document( kvp("path", "patientRecord.ssn"), kvp("bsonType", "string"), kvp("keyId", bsoncxx::types::b_null{}), kvp("queries", make_document( kvp("queryType", "prefix"), kvp("strMinQueryLength", 3), kvp("strMaxQueryLength", 10), kvp("caseSensitive", true), kvp("diacriticSensitive", true))))))); Tip
Suffix Query
To enable suffix queries on a field, change the
queryTypeoption to"suffix"in the preceding code example.The following example enables substring queries on the
patientRecord.ssnfield:auto const encrypted_fields = make_document(kvp("fields", bsoncxx::builder::basic::make_array( make_document( kvp("path", "patientRecord.ssn"), kvp("bsonType", "string"), kvp("keyId", bsoncxx::types::b_null{}), kvp("queries", make_document( kvp("queryType", "substring"), kvp("strMaxLength", 12), kvp("strMinQueryLength", 3), kvp("strMaxQueryLength", 6), kvp("caseSensitive", true), kvp("diacriticSensitive", true)))))));
For extended versions of these steps, see Create an Encryption Schema.
Instantiate a client encryption object to access the API for the encryption helper methods.
mongocxx::options::client_encryption client_encryption_opts{}; client_encryption_opts.key_vault_namespace(key_vault_namespace); client_encryption_opts.key_vault_client(&encrypted_client); client_encryption_opts.kms_providers(kms_providers);
Create the collection.
Important
Explicitly create your collection, rather than creating it implicitly with an insert operation. When you create a collection using createCollection(), MongoDB creates an index on the encrypted fields. Without this index, queries on encrypted fields may run slowly.
Create your encrypted collection by using the encryption helper method accessed through the client_encryption object. This method automatically generates data encryption keys for your encrypted fields and creates the encrypted collection:
auto const create_collection_options = make_document(kvp("encryptedFields", encrypted_fields.view())); bsoncxx::document::value created_collection_options = make_document(); auto encrypted_collection = client_encryption.create_encrypted_collection( encrypted_client.database(encrypted_database_name), encrypted_collection_name, create_collection_options.view(), created_collection_options, kms_provider_name, customer_master_key.view());
Tip
Database vs. Database Name
The method that creates the encrypted collection requires a reference to a database object rather than the database name. You can obtain this reference by using the database() method on your client object.
For additional information, see Enable Queryable Encryption when Creating a Collection.
Insert a document with encrypted fields.
Create a sample document that describes a patient's personal information. Use the encrypted client to insert it into the patients collection, as shown in the following example:
auto const patient_document = make_document( kvp("patientName", "Jon Doe"), kvp("patientId", 12345678), kvp("patientRecord", make_document( kvp("ssn", "987-65-4320"), kvp("billing", make_document( kvp("type", "Visa"), kvp("number", "4111111111111111"))), kvp("billAmount", 1500)))); encrypted_collection.insert_one(patient_document.view());
Specify fields to encrypt.
To encrypt a field, add it to the encryption schema. To enable queries on a field, add the queries property. You can enable fields to be queryable by the following types of queries:
Equality
Range
Prefix, suffix, or substring
The following steps demonstrate how to specify fields to encrypt with each query type.
Specify fields for equality queries.
To enable equality queries on a field, add the field to the encryption schema with a
queryTypeof"equality". The following code sample encrypts both thessnandbillingfields, but only thessnfield is queryable:$collectionOpts = [ 'encryptedFields' => [ 'fields' => [ [ 'path' => 'patientRecord.ssn', 'bsonType' => 'string', 'queries' => ['queryType' => 'equality'], 'keyId' => null, ], [ 'path' => 'patientRecord.billing', 'bsonType' => 'object', 'keyId' => null, ], ], ], ]; Specify fields for range queries.
To enable range queries on a field, add the field to the encryption schema with a
queryTypeof"range". The following example adds thebillAmountfield to the encryption schema created in the preceding step and enables range queries on it:$collectionOpts = [ 'encryptedFields' => [ 'fields' => [ [ 'path' => 'patientRecord.ssn', 'bsonType' => 'string', 'queries' => ['queryType' => 'equality'], 'keyId' => null, ], [ 'path' => 'patientRecord.billing', 'bsonType' => 'object', 'keyId' => null, ], [ 'path' => 'patientRecord.billAmount', 'bsonType' => 'int', 'queries' => [ 'queryType' => 'range', 'sparsity' => 1, 'trimFactor' => 4, 'min' => 100, 'max' => 2000, ], 'keyId' => null, ], ], ], ]; Specify fields for prefix, suffix, or substring queries.
To enable prefix, suffix, or substring queries on a field, add the field to the encryption schema with a
queryTypeof"prefix","suffix", or"substring"and the associated options. The following example enables prefix queries on thepatientRecord.ssnfield:$collectionOpts = [ 'encryptedFields' => [ 'fields' => [ [ 'path' => 'patientRecord.ssn', 'bsonType' => 'string', 'queries' => [ 'queryType' => 'prefix', 'strMinQueryLength' => 3, 'strMaxQueryLength' => 10, 'caseSensitive' => true, 'diacriticSensitive' => true, ], 'keyId' => null, ], ], ], ]; Tip
Suffix Query
To enable suffix queries on a field, change the
queryTypeoption to"suffix"in the preceding code example.The following example enables substring queries on the
patientRecord.ssnfield:$collectionOpts = [ 'encryptedFields' => [ 'fields' => [ [ 'path' => 'patientRecord.ssn', 'bsonType' => 'string', 'queries' => [ 'queryType' => 'substring', 'strMaxLength' => 12, 'strMinQueryLength' => 3, 'strMaxQueryLength' => 6, 'caseSensitive' => true, 'diacriticSensitive' => true, ], 'keyId' => null, ], ], ], ];
For extended versions of these steps, see Create an Encryption Schema.
Create the collection.
Important
Explicitly create your collection, rather than creating it implicitly with an insert operation. When you create a collection using createCollection(), MongoDB creates an index on the encrypted fields. Without this index, queries on encrypted fields may run slowly.
Create your encrypted collection by calling the createEncryptedCollection() method on your database. This method automatically generates data encryption keys for your encrypted fields and creates the encrypted collection:
$encryptedClient->getDatabase($encryptedDatabaseName)->createEncryptedCollection( $encryptedCollectionName, $clientEncryption, $kmsProviderName, $customerMasterKeyCredentials, $collectionOpts, );
For additional information, see Enable Queryable Encryption when Creating a Collection.
Insert a document with encrypted fields.
Create a sample document that describes a patient's personal information. Use the encrypted client to insert it into the patients collection, as shown in the following example:
$patientDocument = [ 'patientName' => 'Jon Doe', 'patientId' => 12345678, 'patientRecord' => [ 'ssn' => '987-65-4320', 'billing' => [ 'type' => 'Visa', 'number' => '4111111111111111', ], 'billAmount' => 1500, ], ]; $encryptedCollection = $encryptedClient ->getDatabase($encryptedDatabaseName) ->getCollection($encryptedCollectionName); $result = $encryptedCollection->insertOne($patientDocument);
Specify fields to encrypt.
To encrypt a field, add it to the encryption schema. To enable queries on a field, add the queries property. You can enable fields to be queryable by the following types of queries:
Equality
Range
Prefix, suffix, or substring
The following steps demonstrate how to specify fields to encrypt with each query type.
Specify fields for equality queries.
To enable equality queries on a field, add the field to the encryption schema with a
queryTypeof"equality". The following code sample encrypts both thessnandbillingfields, but only thessnfield is queryable:collection_opts = { encrypted_fields: { fields: [ { path: "patientRecord.ssn", bsonType: "string", queries: { queryType: "equality" }, keyId: nil }, { path: "patientRecord.billing", bsonType: "object", keyId: nil } ] } } Specify fields for range queries.
To enable range queries on a field, add the field to the encryption schema with a
queryTypeof"range". The following example adds thebillAmountfield to the encryption schema created in the preceding step and enables range queries on it:collection_opts = { encrypted_fields: { fields: [ { path: "patientRecord.ssn", bsonType: "string", queries: { queryType: "equality" }, keyId: nil }, { path: "patientRecord.billing", bsonType: "object", keyId: nil }, { path: "patientRecord.billAmount", bsonType: "int", queries: { queryType: "range", sparsity: 1, trimFactor: 4, min: 100, max: 2000 }, keyId: nil } ] } } Specify fields for prefix, suffix, or substring queries.
To enable prefix, suffix, or substring queries on a field, add the field to the encryption schema with a
queryTypeof"prefix","suffix", or"substring"and the associated options. The following example enables prefix queries on thepatientRecord.ssnfield:collection_opts = { encrypted_fields: { fields: [ { path: "patientRecord.ssn", bsonType: "string", queries: { queryType: "prefix", strMinQueryLength: 3, strMaxQueryLength: 10, caseSensitive: true, diacriticSensitive: true }, keyId: nil } ] } } Tip
Suffix Query
To enable suffix queries on a field, change the
queryTypeoption to"suffix"in the preceding code example.The following example enables substring queries on the
patientRecord.ssnfield:collection_opts = { encrypted_fields: { fields: [ { path: "patientRecord.ssn", bsonType: "string", queries: { queryType: "substring", strMaxLength: 12, strMinQueryLength: 3, strMaxQueryLength: 6, caseSensitive: true, diacriticSensitive: true }, keyId: nil } ] } }
For extended versions of these steps, see Create an Encryption Schema.
Create the collection.
Important
Explicitly create your collection, rather than creating it implicitly with an insert operation. When you create a collection using createCollection(), MongoDB creates an index on the encrypted fields. Without this index, queries on encrypted fields may run slowly.
Create your encrypted collection by using the encryption helper method accessed through the ClientEncryption class, as shown in the following example:
client_encryption.create_encrypted_collection( encrypted_client.use(encrypted_database_name).database, encrypted_collection_name, collection_opts, kms_provider_name, customer_master_key_credentials )
This method automatically generates data encryption keys for your encrypted fields and creates the encrypted collection.
Tip
Database vs. Database Name
The method that creates the encrypted collection requires a reference to a database object rather than the database name. You can obtain this reference by using a method on your client object.
For additional information, see Enable Queryable Encryption when Creating a Collection.
Insert a document with encrypted fields.
Create a sample document that describes a patient's personal information. Use the encrypted client to insert it into the patients collection, as shown in the following example:
patient_document = { patientName: "Jon Doe", patientId: 12345678, patientRecord: { ssn: "987-65-4320", billing: { type: "Visa", number: "4111111111111111" }, billAmount: 1500 } } encrypted_collection = encrypted_client .use(encrypted_database_name)[encrypted_collection_name] result = encrypted_collection.insert_one(patient_document)
Next Steps
After creating a Queryable Encryption-enabled collection, you can query the encrypted fields.