[CSHARP-4745] Unable to cast object of type 'MongoDB.Bson.BsonArray' to type 'MongoDB.Bson.BsonDocument' Created: 05/Aug/23  Updated: 27/Oct/23  Resolved: 27/Oct/23

Status: Closed
Project: C# Driver
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Minor - P4
Reporter: A B Assignee: Robert Stam
Resolution: Gone away Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Related
related to CSHARP-4293 Update with aggregation pipeline fail... Closed
is related to CSHARP-4746 PipelineUpdateDefinition cannot be co... Closed
is related to CSHARP-4747 Add support for $set stage Closed
Documentation Changes Summary:

1. What would you like to communicate to the user about this feature?
2. Would you like the user to see examples of the syntax and/or executable code and its output?
3. Which versions of the driver/connector does this apply to?


 Description   

This code

new PipelineUpdateDefinition<MyDocument>(
    new EmptyPipelineDefinition<MyDocument>()
        .Match(a => a.MyObject == null))
            .Set(a => a.MyObject, new MyDocument.MyObject())
            .Render(
                BsonSerializer.SerializerRegistry.GetSerializer<MyDocument>(),
                BsonSerializer.SerializerRegistry
            ).ToBsonDocument();

Gives me this error:

System.InvalidCastException:
Unable to cast object of type 'MongoDB.Bson.BsonArray' to type 'MongoDB.Bson.BsonDocument'.

I think it is a bug.



 Comments   
Comment by Robert Stam [ 27/Oct/23 ]

Closing this ticket because now that CSHARP-4747 has been addressed we have support for a $set stage.

Comment by A B [ 09/Aug/23 ]

@james.kovacs@gmail.com

I can't even do that ☹️

See the screenshot over in:
https://jira.mongodb.org/browse/SERVER-79819

Comment by James Kovacs [ 09/Aug/23 ]

Hi, Riz,

I reached out to our JIRA admins. Usernames come from the single sign-on providers and that username is the email address. Unfortunately username and email address are inextricably linked given how the SSO providers integrate with JIRA. My only suggestion is to use an alternate email address created for JIRA logins and notifications.

Sincerely,
James

Comment by A B [ 08/Aug/23 ]

I was trying to do this with aggregation pipelines:

(my question on Stack Overflow) https://stackoverflow.com/q/76813584

The plan was to have an aggregation pipeline that looks like this:

  1. If X is NULL, set X to [NEW COMPLEX OBJECT]
  2. Set X.A
  3. Set X.B
  4. ...

Or:

  1. If X is NULL, set X to [NEW COMPLEX OBJECT (with A, B ...)]
  2. Else:
    1. Set X.A
    2. Set X.B
    3. ...

The update operation does auto create field X if NULL or missing, but,

this isn't useful if the CLASS based data model in code has additional properties

which are evaluated upon construction (with the C# NEW keyword).

Such as a date/time property with an auto property initializer.

Comment by Robert Stam [ 07/Aug/23 ]

I'm making an educated guess at what you are trying to accomplish. I think the correct version of what you are trying to do is:

var filter = Builders<MyDocument>.Filter.Where(x => x.MyObject == null);
var pipeline =
    new EmptyPipelineDefinition<MyDocument>()
    .AppendStage<MyDocument, MyDocument, MyDocument>("{ $set : { MyObject : { X : 1 } } }");
var update = new PipelineUpdateDefinition<MyDocument>(pipeline);
 
var result = collection.UpdateOne(filter, update);

Notice in particular that when using a pipeline to update documents the filter is NOT part of the pipeline, but rather is specified separately.

Also, we don't yet have type safe builder support for the `$set` pipeline stage, so currently the only way to use a `$set` stage is to create the stage manually and use the general purpose `AppendStage` method.

I have created CSHARP-4746 to track builder support for the `$set` stage.

You don't actually have to use a pipeline for this simple update, where you are simply setting the value of a field. You could just use:

var collection = GetCollection(linqProvider);
var filter = Builders<MyDocument>.Filter.Where(x => x.MyObject == null);
var update = Builders<MyDocument>.Update.Set(x => x.MyObject, new MyObject { X = 1 });
 
var result = collection.UpdateOne(filter, update);

Comment by Robert Stam [ 07/Aug/23 ]

Part of the issue here in CSHARP-4745 is that we don't yet have support for the $set pipeline stage.

Comment by Robert Stam [ 07/Aug/23 ]

Part of the issue here in CSHARP-4745 is an attempt to combine a PipelineUpdateDefinition with another UpdateDefinition.

Comment by A B [ 07/Aug/23 ]

As suspected, this issue shows up in search results for: https://www.google.com/search?q="<email address>" 🫤

Comment by A B [ 07/Aug/23 ]

Also the Status needs updating 🙂

Comment by A B [ 07/Aug/23 ]

@robert@mongodb.com

You are aware that your email address is part of your Jira user name right? That we have no control over.

Hmm, I see, do the admin(s) of the MongoDB JIRA have a mode of contact for external users?

By the way, as you are aware, this email address visibility issue affects all users, including MongoDB employees.

Comment by Robert Stam [ 06/Aug/23 ]

Thank you for reporting this. I am able to reproduce the exception you are seeing (though I did have to guess at your class declarations to be able to compile and run a test).

We will investigate further and let you know what the root cause is and what we can do about it.

Comment by Robert Stam [ 06/Aug/23 ]

A B, I have edited the PM Bot comment so that "A B" is not a link.

You are aware that your email address is part of your Jira user name right? That we have no control over.

Comment by A B [ 05/Aug/23 ]

james.kovacs@mongodb.com hi, could you please remove the first comment from dbeng-pm-bot, my email address is publicly visible when not logged in (Hi <email>).

Comment by PM Bot [ 05/Aug/23 ]

Hi A B, thank you for reporting this issue! The team will look into it and get back to you soon.

Generated at Wed Feb 07 21:49:14 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.