How to update object using where condition in CosmoDb with DocumentDb api - c#

Using CosmoDb with MongoDb api from c# I can update a document with filter condition rather than using the Id.
For example this code work fine with CosmoDb with MongoDb api.
public bool UpdateTask(MyTask myTask)
{
var mongoCollection = GetBsonCollectionForEdit();
var builder = Builders<BsonDocument>.Filter;
var filterName = builder.Eq("Name", myTask.Name);
var filterCategory = builder.Eq("Category", myTask.Category);
var filter = builder.And(new[] { filterName, filterCategory });
var replaceUpdate = Builders<BsonDocument>.Update;
var ret = mongoCollection.ReplaceOne(filter, myTask.ToBsonDocument());
return ret.ModifiedCount == 1;
}
Can I do the same thing with CosmoDb using the SQL DocumentDb api ?
(Without implement UDF or StoredPoc)
Thanks

No, but you can perform a query for the criteria using CreateDocumentQuery, then iterate through the matching IDs and perform an update on each of them using ReplaceDocumentAsync.

Related

Select statement use Microsoft.Azure.Documents

I'm developing a project using CosmosDb and Microsoft Azure Document library with c#.
I want to execute a stored procedure that retrieve all the record of a contsiner but the code retrieve only 100 record.
The code is the following :
string collectionToUse;
string partition;
if (typeof(T).ToString().IndexOf("Telemetry") != -1)
{
DocumentDBRepository<EBB.Web.Telemerty.Models.Telemetry>.Initialize();
collectionToUse = AppSettings.collection;
partition = "id";
}
else
{
DocumentDBRepository<EBB.Web.Telemerty.Models.Events>.Initialize();
collectionToUse = AppSettings.collection2;
partition = "uid";
}
Uri uri =
UriFactory.CreateStoredProcedureUri(AppSettings.database, collectionToUse, AppSettings.spName);
RequestOptions options = new RequestOptions { PartitionKey = new PartitionKey(partition) };
var result = await client.ExecuteStoredProcedureAsync<string>(uri, options, null);
List<T> list = new List<T>();
list = JsonConvert.DeserializeObject<List<T>>(result.Response);
return list;
What is the problem?
Thanks in advance for help me.
Simone
In Cosmos DB stored procedures cannot return all the documents in the container because the scope of the stored procedure execution isn't the full container but rather ONLY the logical partition that you specify in the RequestOptions. This means that your SP will only return documents that have this logical partition value in their properties.

I want to copy documents from one collection to another

I have 2 collections in my database. Let's say collection_1 and collection_2. I want to copy or move all of my documents in collection_1 to collection_2 using C#.
Any idea please?
Here's a solution to copy between databases. If they are on the same database then it is even more simple, just use one mongo client
var fromConnectionString = "mongodb://localhost:27017"; // if copy between same database then obviously you only need one connectionstring and one MongoClient
var toConnectionString = "mongodb://localhost:27017";
var sourceClient = new MongoClient(fromConnectionString);
var copyFromDb = sourceClient.GetDatabase("CopyFromDatabaseName");
var copyCollection = copyFromDb.GetCollection<BsonDocument>("FromCollectionName").AsQueryable(); // or use the c# class in the collection
var targetClient = new MongoClient(toConnectionString);
var targetMongoDb = targetClient.GetDatabase("CopyToDatabase");
var targetCollection = targetMongoDb.GetCollection<BsonDocument>("ToCollectionName");
targetCollection.InsertMany(copyCollection);
With database query.
Source :https://docs.mongodb.com/manual/reference/method/db.cloneCollection/
db.cloneCollection('mongodb.example.net:27017', 'profiles', { 'active' : true } )
With C#
Source: Duplicate a mongodb collection
var source = db.GetCollection("test");
var dest = db.GetCollection("testcopy");
dest.InsertBatch(source.FindAll());

Find all MongoDB documents from a list of ids using `in` operator

i am trying to find documents in collection by ids. Most of the suggested answers use C# class that matches with the document. something like here
var filter = Builders<Product>.Filter
.In(p => p.Id, productObjectIDs);
i don't have corresponding C# class, so i am using BsonDocument
public async Task<IEnumerable<BsonDocument>> GetData(IEnumerable<int> documentIds)
{
var collection = _mongoDatabase.GetCollection<BsonDocument>("mycollection");
// how do set filter here
var filterBuilder = Builders<BsonDocument>.Filter.In<int>("???????", documentIds);
var projection = Builders<BsonDocument>.Projection
.Include("_id")
.Include("status")
.Include("units");
var result = await collection.Find(filterBuilder).Project<BsonDocument>(projection).ToListAsync().ConfigureAwait(false);
return result;
}
I am not sure how do i set filter with in operator?
You may try this filter:
var filter = new BsonDocument("_id", new BsonDocument("$in", new BsonArray(documetIds)));
Based on this answer

How to convert deprecated IMongoQuery to a FilterDefinitionBuilder

I've got a Visual Studio C# project that's using the MongoDB driver v2.0, and I am attempting to update it to use driver v2.3.0.
There's a section of code which builds a list of IMongoQuery entries based on the presence of various search fields, e.g.
var queryList = new List<IMongoQuery>();
if (!string.IsNullOrEmpty(searchField1))
queryList.Add(Query.Matches(sKey1, searchField1));
...
if (!string.IsNullOrEmpty(searchFieldN))
queryList.Add(Query.Matches(sKeyN, searchFieldN));
How do I convert this to the new FilterDefinitionBuilder syntax? I don't see a similar Add() method in its interface.
UPDATE:
Here's what I'm currently doing, and it is UGLY! Please let me know if there's a better way to do this.
var builder = Builders<BsonDocument>.Filter;
FilterDefinition<BsonDocument> filter = null;
// do this for each search field
if (!string.IsNullOrEmpty(searchField1))
{
if (filter == null)
filter = builder.Eq(sKey1, searchField1);
else
filter = filter & builder.Eq(sKey1, searchField1);
}
I know long time passed but just in case anyone else comes here looking for a solution, here is 2.3.12 compatible way
//create a filter definition builder
var fdefb = new FilterDefinitionBuilder<BsonDocument>(); //or FilterDefinitionBuilder<TModel>
//create a list of Filter Definitions
var queryList = new List<FilterDefinition<BsonDocument>>(); //or List<FilterDefinition<TModel>>
// do this for each search field
if (!string.IsNullOrEmpty(searchField1))
{
if (filter == null)
filter = fdefb.Eq(sKey1, BsonValue.Create(searchField1));
else
filter &= fdefb.Eq(sKey1, BsonValue.Create(searchField1));
}

how to search on mongodb by using runcommand

This is my code... but runcommand doesn't get any results
Notice : "title" is an indexed field
var mongoClient = new MongoClient(ConfigurationManager.AppSettings["connectionString"]);
var server = mongoClient.GetServer();
mongodatabase = server.GetDatabase("Htmlattachment2");
MongoCollection<Department> attachments = mongodatabase.GetCollection<Department>("attachment2");
attachments.EnsureIndex(new IndexKeysBuilder().Ascending("title"));
attachments.Insert(new BsonDocument("title", "The quick brown fox"));
var t = attachments.GetIndexes().ToList();
//foreach (Attachements emp in attachments.FindAll())
//{ }
var textSearchCommand = new CommandDocument
{
{ "text","title" },
{ "search", textBox1.Text }
};
var commandResult = mongodatabase.RunCommand(textSearchCommand);
var response = commandResult.Response["results"].AsBsonArray;
foreach (BsonDocument result in response)
{
// process result
}
It might be easier if you just used LINQ to perform queries. There is a tutorial on how use LINQ with MongoDB here. Note that the MongoDB C# driver translates the LINQ queries to run on the database as native Mongo queries.

Categories