Updating Embedded Array MongoDB/C# - 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.

Related

Dynamically Query a Mongo Collection in c#

I'm new to C# mongo,earlier worked on Node and Mongo.
i have a collection called tasks.Below is a sample record.
{
"_id" : ObjectId("6193bfba23855443a127466a"),
"taskIdentifier" : LUUID("00000000-0000-0000-0000-000000000000"),
"title" : "PR Liquidators",
"company" : "iuytreugdfh",
"purpose" : "test purpose",
"column" : "Search",
"assignTo" : "Shiva",
"assignToId" : ObjectId("61933b47a79ac615648a7855"),
"assignToImage" : null,
"notes" : "ggh#William james ",
"done" : 0,
"taskID" : "00029",
"status" : "Pending",
"states" : [
"Alabama - AL",
"Alaska - AK"
],
"active" : true,
"updatedAtUtc" : ISODate("2021-11-18T12:26:37.616Z"),
"updatedBy" : ""
}
in my c# webapi Project i always get a array called filterCriteria from api request of below form:
filterCriteria=[
{key:"purpose",value:"test purpose",type:"eq"},
{key:"active",value:true,type:"eq"}
]
Now I want to query the mongo collection tasks using the given filterCriteria.
tried something using LINQ statements but no use --hardcoding works but dynamically not working.
How can I achieve this???
maybe you are looking for Builders:
public enum FilterType{
eq=1,//equal
gt=2//greater than
}
//************
var builder = Builders<FilterCritertiaModel>.Filter;
var query = builder.Empty;
foreach(var filterCriteriaItem in filterCriteria){
switch (filterCriteriaItem.type) {
case eq:
query &= builder.Eq(filterCriteriaItem.Key, filterCriteriaItem.Value);
case gt:
query &=builder.Gt(filterCriteriaItem.Key, filterCriteriaItem.Value);
//all cases....
}

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)

How to find number of distinct fields in a collection in mongodb

As MongoDB provides the flexibility to store the unstructured data,
Is there any way in mongodb C# driver, I can find the number of distinct fields name from a collection.
I mean to say
{
"_id" : ObjectId("52fb69ff1ecf0322f0ab3129"),
"Serial Number" : "1",
"Name" : "Sameer Singh Rathoud",
"Skill" : "C++",
"City" : "Pune",
"Country" : "India"
}
{
"_id" : ObjectId("52fb69ff1ecf0322f0ab312a"),
"Serial Number" : "2",
"Name" : "Prashant Patil",
"DOB" : "31/07/1978",
"Location" : "Hinjewadi",
"State" : "Maharashtra",
"Country" : "India"
}
I want to get [_id, Serial Number, Name, DOB, Skill, City, State, Country]
i also faced this issue. If you till not got proper solution or for new person who searching solution for this kind of question they can use this.
var keys = [];
db.Entity.find().forEach(function(doc){
for (var key in doc){
if(keys.indexOf(key) < 0){
keys.push(key);
}
}
});
print(keys);

MongoDb EnsureIndex looks have a bug

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.

Categories