Michael
Michael

Reputation: 1605

Mongo C# Driver fails Bson Serialization for Compound Must clauses in $search aggregation

I have an Atlas Search index, and I'm using MongoDb Compass to write a $search aggregation, I was able to get the following syntax working and successfully returning results from Compass:

{
  index: "ShipmentProjections",
  compound: {
    must: {
      equals: {
        value: 208414,
        path: "MerchantId",
      },
    },
    must: {
      in: {
        path: "ShipmentId",
        value: [100405234]
      }
    }
  },
}

My problem is that I can’t convert this query into C#. I am using the MongoDb C# Bson driver (Nuget: MongoDb.Bson 2.23.2), but when I try to pass this query into BsonDocument.Parse(searchQuery), I get the following error:

System.InvalidOperationException: Duplicate element name 'must'.
   at MongoDB.Bson.BsonDocument.Add(BsonElement element)
   at MongoDB.Bson.BsonDocument.Add(String name, BsonValue value)
   at MongoDB.Bson.Serialization.Serializers.BsonDocumentSerializer.DeserializeValue(BsonDeserializationContext context, BsonDeserializationArgs args)
   at MongoDB.Bson.Serialization.Serializers.BsonValueSerializerBase`1.Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)
   at MongoDB.Bson.Serialization.IBsonSerializerExtensions.Deserialize[TValue](IBsonSerializer`1 serializer, BsonDeserializationContext context)
   at MongoDB.Bson.Serialization.Serializers.BsonValueSerializer.DeserializeValue(BsonDeserializationContext context, BsonDeserializationArgs args)
   at MongoDB.Bson.Serialization.Serializers.BsonValueSerializerBase`1.Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)
   at MongoDB.Bson.Serialization.IBsonSerializerExtensions.Deserialize[TValue](IBsonSerializer`1 serializer, BsonDeserializationContext context)
   at MongoDB.Bson.Serialization.Serializers.BsonDocumentSerializer.DeserializeValue(BsonDeserializationContext context, BsonDeserializationArgs args)
   at MongoDB.Bson.Serialization.Serializers.BsonValueSerializerBase`1.Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)
   at MongoDB.Bson.Serialization.IBsonSerializerExtensions.Deserialize[TValue](IBsonSerializer`1 serializer, BsonDeserializationContext context)
   at MongoDB.Bson.BsonDocument.Parse(String json)

However, it seems like having duplicate must elements within the compound statement is the required format of the query.

It seems as if there is a conflict between the syntax $search stage is requiring, and the uniqueness constraints on the BsonDocument's keys in the C# driver.

From my testing various ways of writing the query from Compass, I have found:

Is there any way to get the BsonDocument in the C# driver to accept this search query with it’s duplicate must keys? Is there an alternative way to write the same query that avoids the duplicate key issues?

Thanks for your help!

Upvotes: 0

Views: 122

Answers (1)

Michael
Michael

Reputation: 1605

Aha, answer found from another board. It's as simple as converting the must clause to an array.

compound: {
    must: [
      {
        equals: {
          value: 208414,
          path: "MerchantId",
        },
      },
      {
        in: {
          path: "ShipmentId",
          value: [10654081],
        },
      }
    ]
  },

Upvotes: 0

Related Questions