MongoDb EnsureIndex looks have a bug - c#

I am battling strange behavior of index creation from hours. I am trying to re-build my sample datas so i drop my collection before insert new datas and before insert new datas i create indexes again like below.
db.GetCollection("Posts").EnsureIndex("Name","Title","Owner");
After that i am trying to Execute sorted Query but MongoDb throws exception and says that
QueryFailure flag was too much data for sort() with no index. add an index or specify a smaller limit
But if i put this line code db.GetCollection("Post").EnsureIndex("Name"); before execute query, it works without problem. Then i have realized that if i use this before rebuild datas it works. There should to be a bug in overloading method or something i have missed.
I am using 10Gen .net driver version 1.2 and i have checked which indexes exist before execure query. Here it is
db.GetCollection("Posts").EnsureIndex("Name","Title","Owner");
db.GetIndexes();//result
[0]: { "v" : 1, "key" : { "_id" : 1 }, "ns" : "Posts", "name" : "_id_" }
[1]: { "v" : 1, "key" : { "Name" : 1, "Title" : 1, "Owner" : 1 }, "ns" : "Posts", "name" : "Name_1_Title_1_Owner_1_" }
db.GetCollection("Posts").EnsureIndex("Title") // i call this for other indexes too
db.GetIndexes();
[0]: { "v" : 1, "key" : { "_id" : 1 }, "ns" : "Posts", "name" : "_id_" }
[1]: { "v" : 1, "key" : { "Name" : 1 }, "ns" : "Posts", "name" : "Name_1" }
[2]: { "v" : 1, "key" : { "Title" : 1 }, "ns" : "Posts", "name" : "Title_1" }
[4]: { "v" : 1, "key" : { "Owner" : 1 }, "ns" : "Posts", "name" : "Owner_1" }

I can't tell from your example exactly what you think isn't working.
One thing to keep in mind is that EnsureIndex only knows what's going on within your own process. So if you remove an index or drop a collection using the mongo shell EnsureIndex won't pick up on that. You can use CreateIndex instead of EnsureIndex if you want to make sure the index exists regardless of what other processes might have done in the meantime.
Let me know if you can provide more details on how to reproduce what you are seeing.

Related

MongoDB C# List the latest of all entries on a sub document

Is it possible to list all the restaurants and their latest grade, if grades is a an array within a restaurant?
{
"_id" : ObjectId("56bf7957b5e096fd06b755b2"),
"grades" : [
{
"date" : ISODate("2014-11-15T00:00:00.000Z"),
"grade" : "Z",
"score" : 38
},
{
"date" : ISODate("2014-05-02T00:00:00.000Z"),
"grade" : "A",
"score" : 10
},
{
"date" : ISODate("2013-03-02T00:00:00.000Z"),
"grade" : "A",
"score" : 7
},
{
"date" : ISODate("2012-02-10T00:00:00.000Z"),
"grade" : "A",
"score" : 13
}
],
"name" : "Brunos On The Boulevard",
}
I would want to get:
{
"_id" : ObjectId("56bf7957b5e096fd06b755b2"),
"grades" : [
{
"date" : ISODate("2014-11-15T00:00:00.000Z"),
"grade" : "Z",
"score" : 38
}
],
"name" : "Brunos On The Boulevard",
}
Explanation
The answer below uses the unwind operator. There's a really simple explanation of it on this answer, should anyone be confused by it as I was.
An option could be doing an aggregate with two operations, an Unwind which deconstructs your array field from the input documents to output a document for each element, and later a sort operation by date in descending order. This way you can get the result you are expected selecting the first element from the aggregate result:
var result = collection.Aggregate()
.Unwind(e => e["grades"])
.SortByDescending(e=>e["grades.date"])
.FirstOrDefault();

C# MongoDB index causes weird duplicate exceptions

we have a problem with our indexes. We have an index on our emails but it throws errors like such:
> db.User.insert({email: "hell33o#gmail.com", "_id" : BinData(3,"iKyq6FvBCdd54TdxxX0JhA==")})
WriteResult({
"nInserted" : 0,
"writeError" : {
"code" : 11000,
"errmsg" : "E11000 duplicate key error index: placetobe.User.$email_text dup key: { : \"com\", : 0.6666666666666666 }"
}
})
when we have the index created with our C# driver like this
Created by C# with:
CreateIndexOptions options = new CreateIndexOptions {Unique = true};
_collection.Indexes.CreateOneAsync(Builders<User>.IndexKeys.Text(_ => _.email), options);
resulted in
{
"v" : 1,
"unique" : true,
"key" : {
"_fts" : "text",
"_ftsx" : 1
},
"name" : "email_text",
"ns" : "placetobe.User",
"weights" : {
"email" : 1
},
"default_language" : "english",
"language_override" : "language",
"textIndexVersion" : 2
}
but if we create it with the MongoDB console like this it works:
{
"v" : 1,
"unique" : true,
"key" : {
"email" : 1
},
"name" : "email_1",
"ns" : "placetobe.User"
}
I don't understand the difference between the two indexes, but they have an effect on our DB. We also have problems with a Collectin that saves names. we get duplicate exceptions on "Molly" if we try to insert "Molli". With the emails is seems to give us errors whenever we have two "gmail" emails in the collection or two ".com" emails etc.
This is a University project and we have to turn it in tomorrow. we're really in trouble, help would be much appreciated
You don't want your email to be a text Index. Text indices allow you to search large amounts of text in MongoDB like if you were parsing through comments or something. All you want is to make sure your emails aren't duplicated so you should use an ascending or descending index.
CreateIndexOptions options = new CreateIndexOptions {Unique = true};
_collection.Indexes.CreateOneAsync(Builders<User>.IndexKeys.Ascending(_ => _.email), options)

Updating Embedded Array MongoDB/C#

I have an interesting scenario where I have a 2-level embedded array in a Mongo Document and I can't seem to figure out a way to update elements inside the 2nd level. I've tried ElemMatch but it doesn't seem to be working.
I have a Product document which has an Attributes array. This Attributes Array has multiple options. Ex. a Product could be a t-shirt, with attributes Size, Color. Each Attribute could have options. For e.g. Size has options XS, S, M, L. Now I want the ability to update the size option given the OptionId (and/or the Attribute Id).
Here's how my Mongo document looks like:
{
"Attributes" : [{
"_id" : ObjectId("52adf86912a4590a3cb322a5"),
"Name" : "Size",
"LabelText" : "Select your T-Shirt Size",
"Description" : "This is the Size of the T-Shirt",
"ShowOnDisplay" : true,
"Options" : [{
"_id" : ObjectId("52adf86912a4590a3cb322a6"),
"Name" : "XS",
"Value" : "XS"
}, {
"_id" : ObjectId("52adf86912a4590a3cb322a7"),
"Name" : "S",
"Value" : "S"
}],
"DateCreatedUtc" : new Date("12/15/2013 10:43:53"),
"DateModifiedUtc" : new Date("12/15/2013 10:43:53")
}],
"AvailableEndTimeUtc" : null,
"AvailableStartTimeUtc" : null,
"Name" : "CMR Dazzle T-Shirt ",
"Price" : {
"Value" : "25",
"Currency" : "USD"
},
"Sku" : "SKU7fb3a",
"_id" : ObjectId("52adf86912a4590a3cb322a4")
}
In the example above, I'd like to update the XS to say "X-Small". I have both the Attribute Id and the Option Id available.
I've tried using ElemMatch, I've tried simple Query.EQ("Attributes.Options._id") and then used update and nothing works. Similar to that, I'd also like to delete an option given an id.
I would greatly appreciate any help here.
I think what you want to do is the same as being discussed here. This is currently not possible in Mongo, see this JIRA.

How to get mongo TTL to expire in c#

Mongo isn't expiring old collections. I checked to make sure my index is type date.
var keys = IndexKeys.Ascending("expiry");
var options = IndexOptions.SetTimeToLive(TimeSpan.FromMinutes(1));
collection.EnsureIndex(keys, options);
this.ExpireDate = new BsonDateTime(DateTime.UtcNow.AddMinutes(5));
var insertResult = collection.Insert(this);
Any tips would be gladly appreciated.
[
{
"v" : 1,
"key" : {
"_id" : 1
},
"ns" : "Showsv1.ShowInfo",
"name" : "_id_"
},
{
"v" : 1,
"key" : {
"expiry" : 1
},
"ns" : "Showsv1.ShowInfo",
"name" : "expiry_1",
"expireAfterSeconds" : 60
}
]
"expiry" : ISODate("2013-02-15T02:40:45.876Z")
The code was missing [BsonElement("expiry")] on top of the ExpireTime property.
Thanks #WiredPrairie for the tip.

Compare the field values in MongoDB

i have two collection A and B
for A contains
{
"_id" : ObjectId("4fb2143af31dfd122ce39c4b"),
"Name" : "Freelander 2.2D",
"Manufacture" : "Landrover"
}
and B ,
{
"_id" : ObjectId("4fb21439f31dfd122ce39c4a")
"Name" : "Rangerover",
"Manufacture" : "Landrover",
}
let me know how to check field values same(here it is "Name" have different values) for A and B in C# driver .If it finds differences i need to update too
Please shed some light on this,Thanks in advance
You can't do queries that involve more than one collection. One query - one collection, period.
Well, Sergio is mostly right (I can't see a way to do this using a language driver), but it is possible using the shell:
var a_in_b = function(o){
var numB = db.B.find({Name:o.Name}).count();
if (numB > 0) print (o.Name + " is in both A and B");
}
> db.A.find()
{ "_id" : ObjectId("4fb2143af31dfd122ce39c4b"), "Name" : "Freelander 2.2D", "Manufacture" : "Landrover" }
> db.B.find()
{ "_id" : ObjectId("4fb667d60569d84fec6ef57e"), "Name" : "Rangerover", "Manufacture" : "Landrover" }
{ "_id" : ObjectId("4fb66a830569d84fec6ef57f"), "Name" : "Freelander 2.2D", "Manufacture" : "Landrover" }
> db.A.find().forEach(a_in_b);
Freelander 2.2D is in both A and B
If your requirement is an admin-related one, this might be what you're looking for. If you're wanting to do this from the C# driver (like a SQL join, I guess), then no, you can't.

Categories