I'm trying to make a simple query to mongoDB using C# Driver.
I've been trying a lot of things and then I came to this but it Always returns null.
Does anyone know if what could it be?
IMongoCollection<BsonDocument> users = Utilities.getCicCollection("Users");
var builder = Builders<BsonDocument>.Filter;
var filter= builder.Eq("Username", "test#test.it") & builder.Eq("Password", "testing");
var result = users.Find(filter).FirstOrDefault();
return (result!=null?true:false);
Use the standard snippet
var collection = _database.GetCollection<BsonDocument>("Users");
var builder = Builders<BsonDocument>.Filter;
var filter = builder.Eq("Username", "test#test.it") & builder.Eq("Password", "testing");
var list = await collection.Find(filter).ToListAsync()
var result = list.FirstOrDefault();
Related
I can use the following for exact matches on loosely typed data in MongoDB:
var mongoClient = new MongoClient(con);
IMongoDatabase mongoDatabase = mongoClient.GetDatabase("mydb");
var profile = mongoDatabase.GetCollection<BsonDocument>("profiles");
var query = profile.AsQueryable();
var results = query.Where(x => x["first_name"] == "john").Take(10);
But how do I use the same approach to do StartsWith and Contains?
I tried:
var results = query.Where(x => x["first_name"].AsString.Contains("john")).Take(10);
But I get the error:
Method 'Boolean Contains(System.String)' declared on type 'System.String' cannot be called with an instance of type 'MongoDB.Bson.BsonValue'
How do I use these filters?
If you cast to string instead of using AsString, it should work:
var results = query.Where(x => ((string) x["first_name"]).Contains("john")).Take(10);
MongoDB .NET Driver provides LinqExtensions.Inject that you can inject FilterDefinition into a LINQ where clause.
Start with Filter
using MongoDB.Driver.Linq;
var filter = Builders<BsonDocument>
.Filter
.Regex("first_name", "^" + "john" + ".*");
var results = query.Where(x => filter.Inject())
.Take(10);
Contains Filter
using MongoDB.Driver.Linq;
var filter = Builders<BsonDocument>
.Filter
.Regex("first_name", "john");
var results = query.Where(x => filter.Inject())
.Take(10);
I've been trying to Sort a collection using MongoDB SortDefinition but whenever I "sort" the collection via a single sort definition, all I get returned is an empty list. However, when I use more than one sort definitions, it returns values.
var TestSort1 = Builders<Scenario>.Sort.Ascending("Name");
var filtered1 = await _context
.DbCollection
.Find(_ => true)
.Sort(TestSort1)
.ToListAsync();
The code above returns an empty list. However, the code below works fine.
var TestSort2 = Builders<Scenario>.Sort.Ascending("Name").Ascending("Owner");
var filtered2 = await _context
.DbCollection
.Find(_ => true)
.Sort(TestSort2)
.ToListAsync();
Is it possible to use a single SortDefinition to sort the collection? Or maybe I am using the SortDefinition wrong?
Maybe you should try using the fluent C# syntax for creating aggregation pipelines...
var collection = database.GetCollection<FiltroCond>("dbCENTRAL");
var filter = Builders<FiltroCond>.Filter.Eq(x => x.PartnerId, cliente)
& Builders<FiltroCond>.Filter.Eq(x => x.TP_PESSOA, 3)
& Builders<FiltroCond>.Filter.Gte(x => x.FG_ATIVO, true);
var result = collection.Aggregate().Match(filter)
.Project(p => new FiltroCond { CD_CLIENTE = p.CD_CLIENTE, ID_CENTRAL = p.ID_CENTRAL, FANTASIA = p.FANTASIA })
.SortBy(p => p.ID_CENTRAL).ToList();
It works fine to me.
Here what I am trying to do is to convert List of Bson Document to the list of Class. The main purpose of doing so is to filter the data from the list of Json data. I am using MongoDb for my database and C# for handling data. I have stored some data in MongoDb and trying to filter the data using FilterDefinition like this:
PROCESS 1
FileContext context = new FileContext();
var collection = context.Db.GetCollection<BsonDocument>("DBCollection");
var builder = Builders<BsonDocument>.Filter;
FilterDefinition<BsonDocument> Filter = builder.Eq("FileName", fileDetail.FileName) & builder.Eq("FileNumber", fileDetail.FileNumber.ToString());
var list = await collection.Find(Filter).ToListAsync();
In this way I am not been able to get the data in list. Therefore, I tried the other way like this:
PROCESS 2
FileContext context = new FileContext();
var collection = context.Db.GetCollection<BsonDocument>("DBCollection");
var list = await collection.Find(_ => true).ToListAsync();
List<MyClass> objList = null;
foreach (var item in objList)
{
objList = new List<MyClass>();
objList.Add(BsonSerializer.Deserialize<MyClass>(item));
}
if(objList.Count >0)
{
int count = objList.Where(x => x.FileName == "SOME_FILE_NAME" && x.FileNumber == 1).Count();
}
This way I am able to get the data and able to filter data as well but I know this is not good programming at all as this will have lots of waiting time if the size of data increases in future.
Here my questions are:
What is wrong in PROCESS 1?
How to Convert List<BsonDocument> to List<MyClass>?
How to filter List<BsonDocument>?
var collection = context.Db.GetCollection<BsonDocument>("DBCollection");
should be:
var collection = context.Db.GetCollection<MyClass>("DBCollection");
That way you should be able to use the Find method to check your FileName and FileNumber using something like:
var objList = await collection.Find(x => x.FileName == "FILENAMEHERE" && x.FileNumber == 1).ToListAsync();
I'm currently upgrading my code to MongoDB C# driver 2.0 and I'm having issues upgrading the code to update documents.
using the old version I was able to do something like this:
MyType myObject; // passed in
var collection = _database.GetCollection<MyType>("myTypes");
var result = collection.Save(myObject);
I'm struggling to find a way to do this in the new version.
I have found a few examples of updating single fields like
var filter = Builders<MyType>.Filter.Eq(s => s.Id, id);
var update = Builders<MyType>.Update.Set(s => s.Description, description);
var result = await collection.UpdateOneAsync(filter, update);
I'd like to update all the fields as I was doing in the old version with the method Save.
Any ideas ?
Thanks a lot
I think you're looking for ReplaceOneAsync():
MyType myObject; // passed in
var filter = Builders<MyType>.Filter.Eq(s => s.Id, id);
var result = await collection.ReplaceOneAsync(filter, myObject)
To add to mnemosyn's answer, while a simple ReplaceOneAsync does update a document it isn't equivalent to Save as Save would also insert the document if it didn't find one to update.
To achieve the same behavior with ReplaceOneAsync you need to use the options parameter:
MyType myObject;
var result = await collection.ReplaceOneAsync(
item => item.Id == id,
myObject,
new UpdateOptions {IsUpsert = true});
you can use LINQ as following:
await context.collection.ReplaceOneAsync(b=> b.Id == item.Id,item);
use ObjectId.Parse(id)
var filter = Builders<MyType>.Filter.Eq(s => s.Id, ObjectId.Parse(id));
var update = Builders<MyType>.Update.Set(s => s.Description, description);
var result = await collection.UpdateOneAsync(filter, update);
My query look like this:
var query = from p in collection
where p.MinStockQuantity >= p.StockQuantity
select p;
I can't run because I have exception: Unsupported filter: ([MinStockQuantity] >= [StockQuantity])
This query also does not work, the same bug.
var collection = database.GetCollection<Product>("Product");
var builder = Builders<Product>.Filter;
var filter = builder.Where(o => o.MinStockQuantity > o.StockQuantity);
var query = collection.Find(filter).ToListAsync().Result;
How can I compare 2 fields ?
I know I am quite late but this works perfectly,try this :
var collection = database.GetCollection<Product>("Product");
var builder = Builders<Product>.Filter;
var filter = builder.Gt(o => o.MinStockQuantity , o.StockQuantity);
var query = collection.Find(filter).ToListAsync().Result;
Gt here is greater than.
there are various other methods like Gte =greater than equal to etc .
So my previous answer was obviously wrong. You shoud use that query
db.products.find({ $where: "this.MinStockQuantity > this.StockQuantity" })
To run this query in c# world you need to use BSON documents:
var doc = MongoDB.Bson.Serialization.BsonSerializer
.Deserialize<BsonDocument>
("{$where: \"this.MinStockQuantity > this.StockQuantity\"}");
var result = collection.Find(new CommandDocument(doc));
I used that query in my test application and it yells proper results.