How to use mongo database queries? - mongodb

I am using MongoDb for my c sharp project instead of mysql, now i want to use query like select * from student Where (name is null or name='XXX') and (sno is null or sno=10), how can i build this query in mongodb.
thanks,
#dinnu.

This should get you started:
var mongoServer = MongoDB.Driver.MongoServer.Create("mongodb://localhost?safe=true");
var mongoDatabase = mongoServer.GetDatabase("test");
var mongoCollection = mongoDatabase.GetCollection<TModel>("Test");
var cursor = mongoCollection.Find(Query.And(
Query.Or(
Query.EQ("Name", "xxx"),
Query.EQ("Name", null)),
Query.Or(
Query.EQ("sno", 10)),
Query.EQ("sno", null)));
Where TModel is the type of the class you want to deserialize from the db. Now you can use cursor to iterate the results of that query, for example:
var someModel = cursor.FirstOrDefault();

Take a look at Fluent Mongo (https://github.com/craiggwilson/fluent-mongo). It adds Linq on top of the official 10gen driver. Thus far I have found using it to be a good experience. It is available via the Nuget or the GitHub.

Related

Index hint with mongodb csharp

I am migrating from the mongodb csharp driver 1.10.0 to 2.0.0.
One of the collection I am using is very big and has to fulfill many queries with different filter attributes. That is why I was relying on some index hint statements. With the v1.10 driver it looks like
myCollection.Find(query).SetHint("myIndexName");
I searched the v2 driver api but this hint method seems to be completly removed in the v2 driver. Is there an alternative? How should I do index hints with the v2 driver?
Note: The Solutions provided works for latest mongodb csharp drivers as well
You can use the FindOptions.Modifiers property.
var modifiers = new BsonDocument("$hint", "myIndexName");
await myCollection.Find(query, new FindOptions { Modifiers = modifiers }).ToListAsync();
May I ask why you are using the hint? Was the server consistently choosing the wrong index? You shouldn't need to do this except in exceptional cases.
Craig
Ideally, try to make the query in a way that mongodb optimizer can use the index automatically.
If you are using FindAsync then you will have a property named Hint. Use it like this:
If you have index named "myIndexName" which you want your query should use forcefully, then use like this:.
BsonString bsonString = new BsonString("myIndexName");
cursor = await collection.FindAsync(y => y.Population > 400000000,
new FindOptions<Person, Person>()
{
BatchSize = 200,
NoCursorTimeout = true,
AllowPartialResults = true,
Projection = "{'_id':1,'Name':1,'Population':1}"
Hint = bsonString.AsBsonValue,
}).ConfigureAwait(false);
You can fine BsonString class in MongoDB.Bson
With agregate you can force indice like this:
BsonString bsonString = new BsonString("ix_indice");
var query = this.collection.Aggregate(new AggregateOptions() { Hint = bsonString }).Match(new BsonDocument {..});
If you are using the Linq IQueryable, you can specify the hint (and other options) like this:
BsonDocument hint = new BsonDocument("myFieldName", 1);
// or
BsonDocument hint = new BsonString("myIndexName");
await collection.AsQueryable(new AggregateOptions { Hint = hint })
myFieldName can also reference a complex field, e.g. Metadata.FileName
myIndexName is the name of an index. I prefer to reference the field (first option) directly, instead of an index, for simple cases.

Mongo DB : Is it possible to know how many Database calls are made to the Mongo DB?

This is my java class that will connect to Mongo DB and fetch the Data .
public class Test
{
public static void main(String args[])
{
DBCursor cursor = null;
DBCollection coll = null;
BasicDBObject query = new BasicDBObject();
String symbol = args[0];
query.put("symbol", "" + symbol);
cursor = coll.find(query);
int count = coll.find(query).count();
}
}
My question is , is it possible to know how many queries are made to the Mongo DB through this program ??
What i want to know is that whether two calls are made to the Mongo DB with this below statements
cursor = coll.find(query);
int count = coll.find(query).count();
Is it possible to know if two calls are amde to the Mongo DB with the above ??
You can use the MongoDB profiling to see the queries that are executed against the server. See the MongoDB documentation for further information: http://docs.mongodb.org/manual/reference/method/db.setProfilingLevel/
In short words: Execute db.setProfilingLevel(2) in your shell and look into the system.profile collection on your server.
If that is the only program connecting to MongoDB you can turn on profiling: http://docs.mongodb.org/manual/tutorial/manage-the-database-profiler/
You would turn profiling upto its max level (2), however if this is just one application of many then there might be (as in PHP) a MongoLog class ( http://php.net/manual/en/class.mongolog.php ) you could use.

MongoDB C# Query for 'NotLike' on string

I'm using official Mongo C# driver. As suggested in answer to one question I'm using the following for the 'like' operator -
Query.Matches("name", "Joe");
My question is how can I achieve the 'NotLike' functionality ?
Assuming you are using the new Query builder in version 1.5, you would do it this way:
var query = Query.Not(Query.Matches("name", "Joe"));
In version 1.5 we also introduced a new typed Query builder, which you could use this way:
var query = Query.Not(Query<C>.Matches(x => x.Name, "Joe"));
Finally, you could also write a LINQ query:
var query = collection.AsQueryable<C>().Where(x => !Regex.IsMatch(x.Name, "Joe"));

MongoDB C# Query Select specific keys from document

How can i do this from c# mongoDb drivers.
sql query :SELECT a,b FROM users
mondb javascript query : db.users.find({}, {a:1,b:1})
How about this:
var database = MongoDatabase.Create(connectionString);
var userCollection = database.GetCollection<Exercise>("users");
var users = userCollection.Find().SetFields("a", "b");
If I understand your question correctly .SetFields does what you want.

How do I get the date a MongoDB collection was created using MongoDB C# driver?

I need to iterate through all of the collections in my MongoDB database and get the time when each of the collections was created (I understand that I could get the timestamp of each object in the collection, but I would rather not go that route if a simpler/faster method exists).
This should give you an idea of what I'm trying to do:
MongoDatabase _database;
// code elided
var result = _database.GetAllCollectionNames().Select(collectionName =>
{
_database.GetCollection( collectionName ) //.{GetCreatedDate())
});
As far as I know, MongoDB doesn't keep track of collection creation dates. However, it's really easy to do this yourself. Add a simple method, something like this, and use it whenever you create a new collection:
public static void CreateCollectionWithMetadata(string collectionName)
{
var result = _db.CreateCollection(collectionName);
if (result.Ok)
{
var collectionMetadata = _db.GetCollection("collectionMetadata");
collectionMetadata.Insert(new { Id = collectionName, Created = DateTime.Now });
}
}
Then whenever you need the information just query the collectionMetadata collection. Or, if you want to use an extension method like in your example, do something like this:
public static DateTime GetCreatedDate(this MongoCollection collection)
{
var collectionMetadata = _db.GetCollection("collectionMetadata");
var metadata = collectionMetadata.FindOneById(collection.Name);
var created = metadata["Created"].AsDateTime;
return created;
}
The "creation date" is not part of the collection's metadata. A collection does not "know" when it was created. Some indexes have an ObjectId() which implies a timestamp, but this is not consistent and not reliable.
Therefore, I don't believe this can be done.
Like Mr. Gates VP say, there is no way using the metadata... but you can get the oldest document in the collection and get it from the _id.
Moreover, you can insert an "empty" document in the collection for that purpose without recurring to maintain another collection.
And it's very easy get the oldest document:
old = db.collection.find({}, {_id}).sort({_id: 1}).limit(1)
dat = old._id.getTimestamp()
By default, all collection has an index over _id field, making the find efficient.
(I using MongoDb 3.6)
Seems like it's some necroposting but anyway: I tried to find an answer and got it:
Checked it in Mongo shell, don't know how to use in C#:
// db.payload_metadata.find().limit(1)
ObjectId("60379be2bec7a3c17e6b662b").getTimestamp()
ISODate("2021-02-25T12:45:22Z")