Uploaded image for project: 'Core Server'
  1. Core Server
  2. SERVER-68371

Enabling CSFLE in your MongoClient causes Atlas Search to fail

    • Fully Compatible
    • ALL
    • v6.1, v6.0
    • Hide

      1. Create a MongoDB Atlas cluster. (M0 is fine.)
      2. Click ... and select Load Sample Dataset.
      3. Select the Search tab.
      4. Click Create Index and create an Atlas Search index on the sample_mflix.movies namespace with default options.
      5. Once the index is done building, run the following C# sample. Note that the line settings.AutoEncryptionOptions = autoEncryptionOptions; is intentionally commented out.
      6. You should see 47 movies returned.
      7. Uncomment settings.AutoEncryptionOptions = autoEncryptionOptions; and run the sample again.
      8. You should see the following exception thrown:
      Command aggregate failed: Unrecognized pipeline stage name: '$search'.

      using System;
      using System.Collections.Generic;
      using MongoDB.Bson;
      using MongoDB.Driver;
      using MongoDB.Driver.Encryption;
      
      var uri = "<<YOUR_MONGODB_ATLAS_URI>>";
      var settings = MongoClientSettings.FromConnectionString(uri);
      
      var localMasterKey = Convert.FromBase64String("Mng0NCt4ZHVUYUJCa1kxNkVyNUR1QURhZ2h2UzR2d2RrZzh0cFBwM3R6NmdWMDFBMUN3YkQ5aXRRMkhGRGdQV09wOGVNYUMxT2k3NjZKelhaQmRCZGJkTXVyZG9uSjFk");
      var kmsProviders = new Dictionary<string, IReadOnlyDictionary<string, object>>();
      var localKey = new Dictionary<string, object>
      {
          { "key", localMasterKey }
      };
      kmsProviders.Add("local", localKey);
      var keyVaultNamespace = CollectionNamespace.FromFullName("encryption.__keyVault");
      var autoEncryptionOptions = new AutoEncryptionOptions(keyVaultNamespace, kmsProviders);
      
      // THIS LINE INTENTIONALLY COMMENTED OUT
      // settings.AutoEncryptionOptions = autoEncryptionOptions;
      
      var client = new MongoClient(settings);
      var db = client.GetDatabase("test");
      var collection = db.GetCollection<BsonDocument>("sample_mflix");
      
      // Simple search example
      var searchStage = @"
      {
          $search : {
              text : {
                  query : 'baseball',
                  path : 'plot'
              }
          }
      }";
      var projection = @"
      {
          _id : 0,
          title : 1,
          plot : 1
      }";
      var pipeline = new EmptyPipelineDefinition<BsonDocument>()
          .AppendStage<BsonDocument, BsonDocument, BsonDocument>(searchStage)
          .Project(projection);
      var moviesAboutBaseball = collection.Aggregate(pipeline).ToList();
      
      Console.WriteLine($"{moviesAboutBaseball.Count} movies about baseball:");
      foreach (var movie in moviesAboutBaseball)
      {
          Console.WriteLine($"  {movie}");
      }
      Console.WriteLine();
      
      Show
      1. Create a MongoDB Atlas cluster. (M0 is fine.) 2. Click ... and select Load Sample Dataset . 3. Select the Search tab. 4. Click Create Index and create an Atlas Search index on the sample_mflix.movies namespace with default options. 5. Once the index is done building, run the following C# sample. Note that the line settings.AutoEncryptionOptions = autoEncryptionOptions; is intentionally commented out. 6. You should see 47 movies returned. 7. Uncomment settings.AutoEncryptionOptions = autoEncryptionOptions; and run the sample again. 8. You should see the following exception thrown: Command aggregate failed: Unrecognized pipeline stage name: '$search'. using System ; using System .Collections.Generic; using MongoDB.Bson; using MongoDB.Driver; using MongoDB.Driver.Encryption; var uri = "<<YOUR_MONGODB_ATLAS_URI>>" ; var settings = MongoClientSettings.FromConnectionString(uri); var localMasterKey = Convert.FromBase64String( "Mng0NCt4ZHVUYUJCa1kxNkVyNUR1QURhZ2h2UzR2d2RrZzh0cFBwM3R6NmdWMDFBMUN3YkQ5aXRRMkhGRGdQV09wOGVNYUMxT2k3NjZKelhaQmRCZGJkTXVyZG9uSjFk" ); var kmsProviders = new Dictionary<string, IReadOnlyDictionary<string, object>>(); var localKey = new Dictionary<string, object> { { "key" , localMasterKey } }; kmsProviders.Add( "local" , localKey); var keyVaultNamespace = CollectionNamespace.FromFullName( "encryption.__keyVault" ); var autoEncryptionOptions = new AutoEncryptionOptions(keyVaultNamespace, kmsProviders); // THIS LINE INTENTIONALLY COMMENTED OUT // settings.AutoEncryptionOptions = autoEncryptionOptions; var client = new MongoClient(settings); var db = client.GetDatabase( "test" ); var collection = db.GetCollection<BsonDocument>( "sample_mflix" ); // Simple search example var searchStage = @" { $search : { text : { query : 'baseball' , path : 'plot' } } }"; var projection = @" { _id : 0, title : 1, plot : 1 }"; var pipeline = new EmptyPipelineDefinition<BsonDocument>() .AppendStage<BsonDocument, BsonDocument, BsonDocument>(searchStage) .Project(projection); var moviesAboutBaseball = collection.Aggregate(pipeline).ToList(); Console.WriteLine($ "{moviesAboutBaseball.Count} movies about baseball:" ); foreach ( var movie in moviesAboutBaseball) { Console.WriteLine($ " {movie}" ); } Console.WriteLine();
    • QO 2022-08-22, QO 2022-09-05, QO 2022-09-19, QO 2022-10-03
    • 167

      When CSFLE is enabled, all commands are sent to the mongocryptd (or the shared library) for processing since drivers do not know which fields must be encrypted. mongocryptd/shared library is not aware of Atlas Search's $search aggregation pipeline stage and errs with:

      Unrecognized pipeline stage name: '$search'.
      

      Because all commands must be sent to mongocryptd/shared library for processing prior to dispatch to a MongoDB Atlas cluster node, Atlas Search ($search) stops working as soon as you enable CSFLE in your MongoClient.

            Assignee:
            jacob.evans@mongodb.com Jacob Evans
            Reporter:
            james.kovacs@mongodb.com James Kovacs
            Votes:
            0 Vote for this issue
            Watchers:
            13 Start watching this issue

              Created:
              Updated:
              Resolved: