Search code examples
javaazureazure-storageazure-cosmosdb

How to specify NONE partition key for deleting a document in Document DB java SDK?


I have only a single collection and when I try to delete the document using the code below

    PartitionKey partitionKey = new PartitionKey("undefined");
    RequestOptions requestOptions=new RequestOptions();
    requestOptions.setPartitionKey(partitionKey);
    for(Document currentDocument: existingIMEIDevice){
        try {
            ConfigVariables.documentClient.deleteDocument(currentDocument.getSelfLink(), requestOptions);
        } catch (DocumentClientException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

it throws exception.

com.microsoft.azure.documentdb.DocumentClientException: Message: {"Errors":["Resource Not Found"]} ActivityId: 4353e7c0-0b24-4b2a-8ec6-fc2db4059aa0, Request URI: /apps/708ed403-166f-44e4-847f-ccaa0cd22d9c/services/d1e2ed4d-7e69-4a3d-9575-3e24b96621b4/partitions/e3fc6138-06a5-4876-a629-a4be69917ded/replicas/131533416718986721p, StatusCode: NotFound at com.microsoft.azure.documentdb.internal.ErrorUtils.maybeThrowException(ErrorUtils.java:69) at com.microsoft.azure.documentdb.internal.GatewayProxy.performDeleteRequest(GatewayProxy.java:187) at com.microsoft.azure.documentdb.internal.GatewayProxy.doDelete(GatewayProxy.java:99) at com.microsoft.azure.documentdb.internal.GatewayProxy.processMessage(GatewayProxy.java:332) at com.microsoft.azure.documentdb.DocumentClient$7.apply(DocumentClient.java:2877) at com.microsoft.azure.documentdb.internal.RetryUtility.executeDocumentClientRequest(RetryUtility.java:58) at com.microsoft.azure.documentdb.DocumentClient.doDelete(DocumentClient.java:2883) at com.microsoft.azure.documentdb.DocumentClient.deleteDocument(DocumentClient.java:956) at com.moveinsync.centraldevices.persistance.AzureCommDAOImpl.replaceDocument(AzureCommDAOImpl.java:45) at com.moveinsync.centraldevices.persistance.AzureCommDAOImpl.documentDbBulkInsert(AzureCommDAOImpl.java:85) at com.moveinsync.centraldevices.jobs.ToAzureJob.executeInternal(ToAzureJob.java:27) at org.springframework.scheduling.quartz.QuartzJobBean.execute(QuartzJobBean.java:75) at org.quartz.core.JobRunShell.run(JobRunShell.java:202) at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:573) If I do not provide RequestOptions it asks me to provide a partition key. I don't have a partition key as the below does not returns anything

SELECT c.partitionKey FROM c ORDER BY c.partitionKey

How do I solve this?


Solution

  • Per my experience, if your collection does not have a partitioning key, you do not need to set the query criteria for the partitioning key when you operate the database.

    In you post, the collection does not have a partitioning key, and you set the partitioning key into RequestOption. So , the database certainly doesn't know where to find the document to operate.

    You could refer to my snippet of code:

    import com.microsoft.azure.documentdb.*;
    
    public class DeleteDocuments {
        private static String accountName="https://jay.documents.azure.com:443/";
    
        private static String accountKey="Czi66skfjZYLTaXuDhoxNb2JHL4DR98VxAxGXtLkWFnjCa5e7gUXQuPgemlXwyPWjjWJpwrseH1wPMfhkqA8cQ==";
    
        private static String databaseName = "db";
    
        private static String collectionName = "coll";
    
        public static void main(String[] args) throws DocumentClientException {
    
            DocumentClient client = new DocumentClient(
                    accountName,
                    accountKey
                    , new ConnectionPolicy(),
                    ConsistencyLevel.Session);
    
            FeedOptions options = null;
            String sql = "select * from c";
            FeedResponse<Document> queryResults  = client.queryDocuments("dbs/"+databaseName+"/colls/"+collectionName, sql, options);
    
            System.out.println("before delete :");
            for (Document d : queryResults.getQueryIterable()) {
                System.out.println(String.format("\tRead %s", d));
            }
    
            RequestOptions requestOptions = new RequestOptions();
            requestOptions.setOfferThroughput(400);
    
            client.deleteDocument("/dbs/"+databaseName+"/colls/"+collectionName+"/docs/1",requestOptions);
    
            queryResults  = client.queryDocuments("dbs/"+databaseName+"/colls/"+collectionName, sql, options);
    
    
            System.out.println("after delete :");
    
            for (Document d : queryResults.getQueryIterable()) {
                System.out.println(String.format("\tRead %s", d));
            }
        }
    }
    

    Update Answer:

    I think you misunderstand the meaning of partitionkey property in the options[].

    For example , my container is created like this:

    enter image description here

    The partition key is "name" for my collection here. You could check your collection's partition key.

    And my documents as below :

    {
        "id": "1",
        "name": "jay"
    }
    
    {
        "id": "2",
        "name": "jay2"
    }
    

    My partitionkey is 'name', so here I have two paritions : 'jay' and 'jay1'.

    So, here you should set the partitionkey property to 'jay' or 'jay2',not 'name'.

    At this point, if I run the code below without setting partition key into RequestOptions, I'll meet the same issue as you.

      RequestOptions requestOptions = new RequestOptions();
      requestOptions.setOfferThroughput(400);
    
            client.deleteDocument("/dbs/"+databaseName+"/colls/"+collectionName+"/docs/1",requestOptions);
    

    Exception in thread "main" java.lang.UnsupportedOperationException: PartitionKey value must be supplied for this operation. at com.microsoft.azure.documentdb.DocumentClient.addPartitionKeyInformation(DocumentClient.java:3199) at com.microsoft.azure.documentdb.DocumentClient.addPartitionKeyInformation(DocumentClient.java:3180) at com.microsoft.azure.documentdb.DocumentClient.deleteDocument(DocumentClient.java:959) at DeleteDocuments.main(DeleteDocuments.java:32)

    I need to set partition key parameter to be the partition where the operated document stored.

     RequestOptions requestOptions = new RequestOptions();
     requestOptions.setOfferThroughput(400);
     PartitionKey partitionKey = new PartitionKey("jay");
     requestOptions.setPartitionKey(partitionKey);
    
            client.deleteDocument("/dbs/"+databaseName+"/colls/"+collectionName+"/docs/1",requestOptions);
    

    Update Answer 2:

    I guess you want to operate the document which does not set partition key.

    Please refer to this perfect blog, you'll find the answer!

    In java code , just set partition key to Undefined.Value() then everything will be done.

     RequestOptions requestOptions = new RequestOptions();
     requestOptions.setOfferThroughput(400);
     PartitionKey partitionKey = new PartitionKey(Undefined.Value());
     requestOptions.setPartitionKey(partitionKey);
    
            client.deleteDocument("/dbs/"+databaseName+"/colls/"+collectionName+"/docs/3",requestOptions);
    

    Hope it helps you.