Uploaded image for project: 'C# Driver'
  1. C# Driver
  2. CSHARP-4240

Feedback on Atlas Search Using C# Driver + Documents in BSON

    • Type: Icon: Improvement Improvement
    • Resolution: Duplicate
    • Priority: Icon: Major - P3 Major - P3
    • None
    • Affects Version/s: None
    • Component/s: None
    • None

      Sharing feedback from client organization on Atlas Search using the C# driver:
       
      For normal Finds and Aggregations, I can write idiomatic C# with a fluent builder API. I can use all the LINQ features I'm used to having on other data structures and database providers.For $search (and $searchMeta!)...I have to either # write the BSON as a string (and worry about escaping query strings properly)

      1. Create nested BsonDocument objects, which gets complicated and nasty very quickly. We ended up writing the helpers in this snippet (and more), which help but are still hard to read. And easy to get wrong if we mess up the structure of the object.

      A normal find query, with all the type-safe "if it builds, it works" LINQ goodness:
      // normal collection Find (where if it builds, it works)
      collection
      .Find(x => x.AnArrayField.Contains(someId))
      .SortByDescending(x => x.ADateField)
      .Project(x => new SomeModel(x.Id, x.Value1, x.Value2))
      .ToList();
       
      // Atlas Search stuff...where if it builds, we're still not sure it will work

      // create text search operator with score boost
      private BsonDocument SearchFieldWithBoost(string field, string value, int Boost)

      { return new("text", new BsonDocument("query", value) .AddRange(new BsonDocument("path", field)) .AddRange(new BsonDocument("score", new BsonDocument("boost", new BsonDocument("value", Boost) ))) ); }


      // Add text search operator with fuzzy parameters
      private BsonDocument GetTextFuzzyStage(string field, string value)

      { return new("text", new BsonDocument("query", value) .AddRange(new BsonDocument("path", field)) .AddRange(new BsonDocument("fuzzy", new BsonDocument("maxEdits", 2) .AddRange(new BsonDocument("prefixLength", 2)) ) ) ); }


      // add numeric filter
      private BsonDocument GetIntEqualsStage(string field, int value)

      { return new("range", new BsonDocument("path", field) .AddRange(new BsonDocument("gte", value)) .AddRange(new BsonDocument("lte", value)) ); }


      // combine must, should, and filter arrays to build compound operator
      private BsonDocument BuildCompoundStage(BsonArray should, BsonArray must, BsonArray filter)

      { var compoundStage = new BsonDocument(); if (must.Any()) compoundStage.AddRange(new BsonDocument("must", must)); if (should.Any()) compoundStage.AddRange(new BsonDocument("should", should)); if (filter.Any()) compoundStage.AddRange(new BsonDocument("filter", filter)); return new BsonDocument("compound", compoundStage); }

       
      A basic user story the user offered is, "As a developer, I would like to use a fluent API and lambda expressions to build $search/$searchMeta aggregation stages that I can be confident are correctly written*.*i.e. only uses fields that are defined in my document model and only uses operators/options that are supported by Search with no typos."

            Assignee:
            Unassigned Unassigned
            Reporter:
            angie.shaw@mongodb.com Angie Shaw
            Votes:
            1 Vote for this issue
            Watchers:
            5 Start watching this issue

              Created:
              Updated:
              Resolved: