How to pull from array of objects using filter

The following works in Mongo shell:

db.computers.update({“dg_mid”: {$eq: “ff4c4ff6-6492-4326-8a41-9a0272c7c265”}}, {$pull: {“comp_users”: {“dg_user”:{$regex: /^DWM/i}}}}`

for Document with the following structure:

{
  "_id": ObjectId("6269593b82bde6eb18b8e9b9"),
  "dg_mid": "021d9bf4-2f3c-4ba9-9963-f34c0e8a3663",
  "comp_type": 0,
  "comp_users": [
    {
       "dg_user": "NETWORK-SERVICE",
       "comp_sid": "S-1-5-20"
    },
    {
       "dg_user": "DWM-254",
       "comp_sid": "S-1-5-19",
             
    },
	{
       "dg_user": "DWM-255",
       "comp_sid": "S-1-5-18",    
     }
   ]
}

Unfortunately I can’t achieve in Java , trying to use Updates.pullByFilter . Such as:

Bson arrayFilter = Filters.regex(“comp_users.dg_user”, Pattern.compile(“^DWM”, Pattern.CASE_INSENSITIVE));

then use updateOne :

collection.updateOne(eq(“dg_mid”, “021d9bf4-2f3c-4ba9-9963-f34c0e8a3663”), pullByFilter(arrayFilter))

failed because of dotted notation comp_users.dg_user in array filter. I tryed to use instead of dotted notation comp_users.$.dg_use as suggested still getting failure. Any suggestion on what I am doing wrong , appreciated

I do not use builder classes because of the extra knowledge you need to have to use them.

I do not use builder classes because I use mongosh extensively and JS and I like my queries and aggregations to be syntactically closed in each language. Builders are an extra layers that I avoid.

For this what I proposed do not use builders, but straight org.bson.Document in a way that is easier for me to use.

I start with the equivalent of
{$regex: /^DWM/i}*
that is easier to map into Java. The equivalent is
{ $regex: "^DWM" , $options : "i" }.

I also use the equivalent
{"dg_mid":"ff4c4ff6-6492-4326-8a41-9a0272c7c265"}
rather than
{"dg_mid": {"$eq": "ff4c4ff6-6492-4326-8a41-9a0272c7c265"}}.

Here it is (n.b. I have not tried to compile or test it):

query = new Document( "dg_mid" ,
  "ff4c4ff6-6492-4326-8a41-9a0272c7c265" ) ;

update = new Document( "$pull" :
  new Document( "comp_users" :
    new Document( "db_users" :
      new Document( "$regex" : "^DWM" ).append( "$options" , "i" ) ) ) ) ;

collection.updateOne( query , update ) ;

Alternatively but relatively slower, you should get the same result with:

query = Document.parse( "{'dg_mid':'ff4c4ff6-6492-4326-8a41-9a0272c7c265'}" ) ;

update = Document.parse( "{'$pull':{'comp_users':{'dg_user':{'$regex':'^DWM','$options':'i'}}}}" ) ;

THX Steeve, I used suggested:
update = Document.parse( "{'$pull':{'comp_users':{'dg_user':{'$regex':'^DWM','$options':'i'}}}}" )

With:

new UpdateOneModel<>(
              eq("dg_mid", id), update, options.upsert(true)));

Since I would like to use Bulk.write , and it works. Thx for help

1 Like