[JAVA-3346] Delete query is systematically created with a "limit" parameter Created: 04/Jul/19  Updated: 27/Oct/23  Resolved: 16/Jul/19

Status: Closed
Project: Java Driver
Component/s: Query Operations
Affects Version/s: 3.6.4
Fix Version/s: None

Type: Bug Priority: Major - P3
Reporter: Debeissat Nicolas Assignee: Ross Lawley
Resolution: Works as Designed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Duplicate
duplicates SERVER-42087 Delete query with limit in query does... Closed
is duplicated by SERVER-42087 Delete query with limit in query does... Closed

 Description   

Hello

The delete requests are created with a "limit" parameter and mongodb does not accept it :

db.domainevents.deleteMany(

{ aggregateIdentifier: "2f13501d-6199-425d-899f-cbd51488ec24", limit: "0" }

)
We did not find any way to change the sent request.

The following code :

https://github.com/mongodb/mongo-java-driver/blob/f27baf179dfc9de5673a06a3326dea66dcf04dca/driver-core/src/main/com/mongodb/operation/BulkWriteBatch.java

systematically adds limit parameter in the request :

writer.writeInt32("limit", deleteRequest.isMulti() ? 0 : 1);

 

Thanks for mongodb

 
 



 Comments   
Comment by Debeissat Nicolas [ 16/Jul/19 ]

Ok thanks, I will look at that representation. I think you can close the ticket.

Comment by Ross Lawley [ 09/Jul/19 ]

Hi debeissat_nicolas,

No problems - so either there is an issue with the AGGREGATE_IDENTIFIER or the UUID. I think its most likely going to be with the UUID - as there are differences in the way drivers have encoded them in the past. Do you know what representation the UUID was encoded in? Was it encoded / saved to MongoDB via the driver or via the shell or via some other driver?

There is an example of how to change the UUID representation in the documentation in that example the representation is changed to UuidRepresentation.STANDARD.

The best approach might be to issue a find query to determine the correct representation. You can use the BsonBinary helper to convert the UUID into a queryable BsonBinary value to quickly help determine the correct representation. (UUID's are stored as BsonBinary values inside MongoDB but different representations have different sub type flags).

I hope that helps,

Ross

Comment by Debeissat Nicolas [ 05/Jul/19 ]

Ok, with the kind of filter you provide, it works thank you.

Sorry for the noise, it seems the legacy code that created the filter (Bson filter= new BasicDBObject(AGGREGATE_IDENTIFIER, uuid)) did not work.

Comment by Ross Lawley [ 05/Jul/19 ]

HI debeissat_nicolas,

Thanks for the ticket - the limit set in the operation will not impact the deleteMany. As you can see from the delete command documentation:

limit The number of matching documents to delete. Specify either a 0 to delete all matching documents or 1 to delete a single document.

Below is a quick test showing it working as expected:

package tour;
 
import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
import org.bson.Document;
 
import java.util.ArrayList;
import java.util.List;
 
/**
 * The QuickTour code example
 */
public class QuickTour {
    /**
     * Run this main method to see the output of this quick example.
     *
     * @param args takes an optional single argument for the connection string
     */
    public static void main(final String[] args) {
        MongoClient mongoClient;
 
        if (args.length == 0) {
            // connect to the local database server
            mongoClient = MongoClients.create();
        } else {
            mongoClient = MongoClients.create(args[0]);
        }
 
        // get handle to "mydb" database
        MongoDatabase database = mongoClient.getDatabase("mydb");
 
        // get a handle to the "test" collection
        MongoCollection<Document> collection = database.getCollection("test");
 
        // drop all the data in it
        collection.drop();
 
        // now, lets add lots of little documents to the collection so we can explore queries and cursors
        List<Document> documents = new ArrayList<Document>();
        for (int i = 0; i < 100; i++) {
            documents.add(new Document("i", i % 2));
        }
        collection.insertMany(documents);
        System.out.println("total # of documents: " + collection.countDocuments());
 
 
        collection.deleteMany(Document.parse("{i: 0}"));
        System.out.println("total # of documents after delete many: " + collection.countDocuments());
 
        collection.drop();
 
        // Clean up
        database.drop();
 
        // release resources
        mongoClient.close();
    }
}

When you run that code you can see that it deletes all the documents where i == 0.

Obviously, if the filter doesn't match any documents then nothing will be deleted. I did notice the filter shown looks like a string representation of UUID - if the aggregateIdentifier was stored as a binary value then the filter wouldn't match any documents.

I hope that helps / provides some insights,

Ross

Generated at Thu Feb 08 08:59:23 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.