2

I would like to know if there is a way to select randomly documents in CosmosDB (Microsoft Azure).

Here is my code, I do not know what to add before "Take(20)":

public List<LeafBook> BooksList { get; private set; }

public async Task<List<LeafBook>> GetBookAsync()
{
    try
    {
        // The query excludes completed TodoItems

        var query = client.CreateDocumentQuery<LeafBook>(collectionLink, new FeedOptions { MaxItemCount = -1 })

             .Take(20)            
             .AsDocumentQuery();

        BooksList = new List<LeafBook>();
        while (query.HasMoreResults)
        {
            BooksList.AddRange(await query.ExecuteNextAsync<LeafBook>());
        }

    }
    catch (Exception e)
    {
        Console.Error.WriteLine(@"ERROR {0}", e.Message);
        return null;
    }
    return BooksList;
}
Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
kikis
  • 103
  • 2
  • 12
  • 2
    There is no native method for extracting random samples (unless you use the MongoDB API with aggregation pipeline). Maybe consider randomizing on a known set of values within your data domain? Date ranges? – David Makogon Dec 26 '18 at 15:30
  • I do not have a approach if you have an Idea I will take – kikis Dec 26 '18 at 15:53
  • Every document has a field : "NumberoftheBook" which is the number of storage of the document (like unique ID for an SQL database) – kikis Dec 26 '18 at 17:12

2 Answers2

1

kikis, as @David Makogon said in the comment, you could follow the sample which is linked by the feedback to get random result in cosmos db mongo api.

However ,there is no such native feature in cosmos db sql api. So , maybe you need to adopt workaround.

You could use stored procedure to implement such feature in cosmos db,please refer to this blog.

In this workaround, the most important thing is that it could potentially iterate through your whole collection, depending on the value of filterString you pass to the sproc upon execution. You should make sure filterString is as lightweight on the database as possible.

Or you could just get 20 random NumberoftheBook properties before the query, and take that for query filter.

Jay Gong
  • 23,163
  • 2
  • 27
  • 32
  • Thanks for your answer. I have tried this to get one document : var query = client.CreateDocumentQuery(collectionLink, new FeedOptions { MaxItemCount = -1 }) .Where(b=> b.NumberOfTheBook==10) .AsDocumentQuery(); but I have this error : System.ArgumentNullException: Value cannot be null. Parameter name: source – kikis Dec 27 '18 at 02:17
  • @kikis You mean you met the error when you use linq to filter documents? – Jay Gong Dec 27 '18 at 08:05
0

Here's how I would do it.

  1. Get the total no of documents in the collection using
    dc.CreateDocumentQuery(update.SelfLink, "SELECT c.id FROM c")

  2. Use Random to select random ints between 0 and the total (minus 1) obtained from above.

  3. Fetch the documents corresponding to the ids obtained (in step 1) at the indexes (in step 2)

I haven't tried this out but let me know!

bit
  • 4,407
  • 1
  • 28
  • 50
  • thanks but I do not know how to adapt : dc.CreateDocumentQuery(update.SelfLink, "SELECT c.id FROM c") with : var query = client.CreateDocumentQuery(collectionLink, new FeedOptions { MaxItemCount = -1 }) .Take(20) .AsDocumentQuery(); – kikis Dec 27 '18 at 10:33