C# MongoDB driver - Change array item position? - mongodb

I wonder if there is a way to change an item's position in an array using C# MongoDB driver?
For example, I have this document:
{
"Item": "X",
"Values": [
{
"Value": 1
},
{
"Value": 2
}
]
}
and I want to change the order of the items in the Values array let's say:
{
"Item": "X",
"Values": [
{
"Value": 2
},
{
"Value": 1
}
]
}
what I'm currently doing is using PullFilter to remove "value": 2" and then use PushEach to insert it at the specific position I need.
But in my case, the array items are large objects so I was wondering if there is a way to just change the item's position without having to remove and re-insert it again.

Related

How can I count all possible subdocument elements for a given top element in Mongo?

Not sure I am using the right terminology here, but assume following oversimplified JSON structure available in Mongo :
{
"_id": 1234,
"labels": {
"label1": {
"id": "l1",
"value": "abc"
},
"label3": {
"id": "l2",
"value": "def"
},
"label5": {
"id": "l3",
"value": "ghi"
},
"label9": {
"id": "l4",
"value": "xyz"
}
}
}
{
"_id": 5678,
"labels": {
"label1": {
"id": "l1",
"value": "hjk"
},
"label5": {
"id": "l5",
"value": "def"
},
"label10": {
"id": "l10",
"value": "ghi"
},
"label24": {
"id": "l24",
"value": "xyz"
}
}
}
I know my base element name (labels in the example), but I do not know the various sub elements I can have (so in this case the labelx names).
How can I group / count the existing elements (like as if I would be using a wildcard) so I would get some distinct overview like
"label1":2
"label3":1
"label5":2
"label9":1
"label10":1
"label24":1
as a result? So far I only found examples where you actually need to know the element names. But I don't know them and want to find some way to get all possible sub element names for a given top element for easy review.
In reality the label names can be pretty wild, I used labelx for readability in the example.
You can try below aggregation in 3.4.
Use $objectToArray to transform object to array of key value pairs followed by $unwind and $group on key to count occurrences.
db.col.aggregate([
{"$project":{"labels":{"$objectToArray":"$labels"}}},
{"$unwind":"$labels"},
{"$group":{"_id":"$labels.k","count":{"$sum":1}}}
])

How do I check if other arrays contain the value I want to add before using $addToSet in mongodb/mongoose?

I want to check if other 'sets' have the value I want to add. If another set has the value, then remove it from that set and add it to the new set.{
"_id": "5a052785aa06c22429717bad",
"word": "wordtest5",
"__v": 0,
"pronunciations": [
{
"pronunciation": "wordtest1",
"_id": "5a052785aa06c22429717bae",
"likes": [
"remove_this",
"5a0508cfcf4f6620786a3cb1"
],
"rating": 1
},
{
"pronunciation": "wordtest5",
"_id": "5a0674c1053ae929db3a576c",
"likes": [],
"rating": 1
},
{
"pronunciation": "testing5",
"_id": "5a06770346be3d2ac6f31561",
"likes": [
"remove_this",
"5a0508cfcf4f6620786a3cb1",
],
"rating": 1
}
]
}
I want to remove all 'remove_this' string inside every 'likes' array.
Use $pull on other 'sets' you mention and use $addToSet on the actual set you want to add. This way you can achieve what you want.
Next time please be very clear on your question.

MongoDB data model for fast reads using array data

I have a dataset which returns an array named "data_arr" that contains anywhere from 5 to 200 subitems which have a labelspace & key-value pair as follows.
{
"other_fields": "other_values",
...
"data_arr":[
{
"labelspace": "A",
"color": "red"
},
{
"labelspace": "A",
"size": 500
},
{
"labelspace": "B",
"shape": "round"
},
]
}
The question is, within MongoDB, how to store this data optimized for fast reads. Specifically, there would be queries:
Comparing key-values (ie. Average size of objects which are both red
and round).
Returning all documents which meet a criteria (ie. Red objects
larger than 300).
Label space is important because some key names are reused.
I've contemplated indexing with the existing structure by indexing labelspace.
I've considered grouping all labelspace key/values into a single sub-document as follows:
{
"other_fields": "other_values",
...
"data_a":
{
"color": "red",
"size": 500
},
"data_b":
{
"shape": "round"
}
}
Or modeling it as follows with a multi-value index
{
"other_fields": "other_values",
...
"data_arr":[
{
"labelspace": "A",
"key": "color",
"value": "red"
},
{
"labelspace": "A",
"key": "size",
"value": 500
},
{
"labelspace": "B",
"key": "shape",
"value": "round"
},
]
}
This is a new data set that needs to be collected. So it's difficult for me to build up enough of a sample only to discover I've ventured down the wrong path.
I think the last one is best suited for indexing, so possibly the best approach?

Project nestsed array elements in MongoDb

I have a collection with documents like this
"_id": ObjectId('55f02a779e6efb8'),
"msgId": "5fdf509c-5229-4e7c-87ff",
"statuses": [
{
"state": "QUEUED",
"timestamp": ISODate('2013-10-08T13:13:38.000Z')
},
{
"state": "PENDING",
"timestamp": ISODate('2013-10-08T13:13:49.000Z')
},
{
"state": "DELIVERED",
"timestamp": ISODate('2013-10-08T13:13:57.000Z')
}
]
I want to use project for assigning the last 2 (embedded docs) values of the nested array (the array size is not static) so as to use them in a group operation in later step.
I want sth like $slice(aggregation) but it is still not supported in the version of MongoDB I use (3.0.6).
Is there any way to access the 2 last elements of the array by their index and if not is there any other solution?

How to Delete a Specific Object From The Arrayof Objects in MongoDB Casbah

mydata is look like below:-
{
"categories": [
{
"categoryname": "Eletronics",
"categoryId": "89sxop",
"displayname": "Eletronics",
"subcategories": [
{
"subcategoryname": "laptop",
"subcategoryId": "454",
"displayname": "Laptop"
},
{
"subcategoryname": "camera",
"subcategoryId": "sony123",
"displayname": "Camera"
}
]
}
]
}
I want to delete a specific object from a Subcategories Array
we are Trying like below code:-(This is to Delete Category)
val removingData = $pull(MongoDBObject("categories" -> MongoDBObject("categoryName" -> "Entertainment")))
this code is for removing Particular category.
But I Want To Remove ONE or MORE subCategories from particular category.
The subCategory(Ex:-i want to Delete camera Object from mydata) from the Electronics category
Expected Output:-(after deleting the camera Object)
{
"categories": [
{
"categoryname": "Eletronics",
"categoryId": "89sxop",
"displayname": "Eletronics",
"subcategories": [
{
"subcategoryname": "laptop",
"subcategoryId": "454",
"displayname": "Laptop"
}
]
}
]
}
Best Regards
GSY
You need to use the $pull operator, specifying the subcategories array and the condition used to pick the elements to remove. The $ operator can be used to select the subcategories array of the specific categories element you're interested in. See the Update Array Operators docs of mongo for details. Something like the following should work:
val query = MongoDBObject("categories.categoryname" -> "Electronics")
val removingData = $pull("categories.$.subcategories" -> MongoDBObject("subcategoryname" -> "camera"))
collection.update(query, removingData)
If you want to remove multiple subcategories, you can use the $or operator to specify multiple subcategorynames