MongoDB - different structure for error "cannot index parallel arrays" - mongodb

i have the following document structure:
{
"_id": "123",
"timestamp": 1628632419,
"propertyA": "A",
"propertyB": "B",
"propertyC": "C",
"propertyD": "D",
"propertyE": "E",
"myArray": [
{
"myNestedArray": [
{
"name": "NestedName1",
"value": "1"
},
{
"name": "NestedName2",
"value": "2"
},
{
"name": "NestedName3",
"value": "3"
}
],
"type": "MyType",
"name": "MyName",
"nestedPropertyA": "A",
"nestedPropertyB": "B",
"nestedPropertyC": "C",
"nestedPropertyD": "D",
"nestedPropertyE": "E",
},
...
]
}
With that, I want to create an index like that:
collection.createIndex({
'myArray.type': 1,
'myArray.myNestedArray.name': 1,
'myArray.myNestedArray.value': 1,
})
This results in:
cannot index parallel arrays
I read through mongoDB's documentation and I understand where the problem is. Now my question is, what is a good structure for my document, in order that my indexing is working?
I found the approach to structure from:
{a:[1,2], b:[8,9]}
to:
{ab:[[1,8], [1,9], [2,8], [2,9]]}
But as I see this approach for my situation, the objects under myArray are too complex.
I was also thinking about moving the array indices as own properties like:
"type": "MyType",
"name": "MyName",
"myNestedArray0": {
"name": "NestedName1",
"value": "1"
},
"myNestedArray1": {
"name": "NestedName2",
"value": "1"
},
...
But this feels wrong and is also not really flexible, furthermore the indexing would be a fix number like:
collection.createIndex({
'myArray.type': 1,
'myArray.myNestedArray0.name': 1,
'myArray.myNestedArray0.value': 1,
'myArray.myNestedArray1.name': 1,
'myArray.myNestedArray1.value': 1,
...
})
Another thought would be, refactoring the myNestedArray to an independent collection. My problem here is, that I need the properties like "propertyA", "propertyB" etc. Furthermore, the myNestedArray could have many entries, so it could multiply the amount of documents immensive.
Can someone give me an advice how to proceed here.

Related

MongoDb Aggregation separated array based on condition

I'm very new to mongodb. I'm trying to do an aggregation pipeline for lookup kinda like SQL left join. Given the following document's schema:
Mongo playground: https://mongoplayground.net/p/yAIwH5V2yv8
Characters:
{
"_id": 1,
"account_id": 1,
"world_id": 0,
"name": "hello"
}
Inventories:
{
"_id": 7,
"character_id": 2,
"type": "EQUIPPED"
}
Items:
{
"_id": 1,
"inventory_id": 7
}
I want to query for characters and look up inventories as well as items in inventories. I was able to achieve this however I would like to separate the inventories field in characters result document.
Current result:
{
"_id": 2,
"account_id": 1,
"world_id": 0,
"name": "hello",
"inventories: [
{
"_id": 1,
"character_id": "2",
"type": "EQUIPPED",
"items: [...]
}
]
}
What I want is based on the type of inventory I want it to be a separate field of the resulted character document something like this:
{
"_id": 2,
"account_id": 1,
"world_id": 0,
"name": "hello",
"equippedInventory: {
"_id": 1,
"character_id": "2",
"type": "EQUIPPED",
"items: [...]
},
"equipInventory: {
"_id": 2,
"character_id": "2",
"type": "EQUIP",
"items: [...]
},
}
Also, is my pipeline the best way to achieve this?

Inserting into selected item of sub array in mongodb

My data is as follows:
{
"_id": {
"$oid": "5e57db66c6bb04eb902589a2"
},
"name": "temp1",
"sub_arr": [{
"_id_": "53",
"_text": "Different ministries & states are working together",
"labels": ["A", "B", "C", "D", "E"]
}, {
"_text": "We need to work together, take small yet important measures to ensure self-protection.",
"_id_": "54",
"labels": ["A", "B", "C", "D", "E", "F"]
}]
}
I can get the item of the subarray that I need as follows:
db.mycollection.find({"name":"temp1"}, {"sub_arr":{"$elemMatch": {"_id_": "54"}}})
Now I would like to insert into that item another sub array as follows:
db.mycollection.find({"name":"temp1"}, {"sub_arr":{"$elemMatch": {"_id_": "54"}}}).upsert.updateOne({'ins_labels': [{"id": "a1", "label": "A"}]})
However it does not work. Please help
db.mycollection.update({"name":"temp1","sub_arr._id_":"54"},{"$set":{"sub_arr.$.ins_labels":[{"id": "a1", "label": "A"}]}})
mongo maintains the position of the array list when array is part of the query.

Update items in a property with array type on MongoDB

I have a collection with documents like:
{
"_id": "Mongo ObjectID",
"some_prop": "some_value",
"features": [
{ "name": "A", "icon": "01.png" },
{ "name": "B", "icon": "02.png" }
]
}
Another document sample:
{
"_id": "Mongo ObjectID",
"some_prop": "other one",
"features": [
{ "name": "B", "icon": "02.png" },
{ "name": "C", "icon": "03.png" },
{ "name": "D", "icon": "04.png" }
]
}
Notice that in the first document and the second there is the same feature B. This occurs all over many documents.
What I need is to update all features B to a new icon, something like this:
{ "name": "B", "icon": "10.png" }
I need to apply this change for all documents that has a feature with name B.
I already did a very horrible code to get all documents and update one by one in a loop. But my guess is there is a better way to do it, maybe in a single collection.update command? I'm new in MongoDB and so far googling didnt work.
You need to use $positional operator to update the fields inside an array
db.collection.updateMany(
{ "features.name": "B" },
{ "$set": { "features.$.icon": "10.png" }}
)

MongoDB query for Find 2 levels object element

I have a big issue, i don't know what to do...
What I wanna is to find all objects with Object2 name. I have Object 2 with name element.
What I wanna is to find all objects with the value X in the element name inside Object2. in the example is the value name is ="IWANTALLOBJECTSWITHTHISNAME"
the Json structure.
"objects": [
{
"_id": "5c69a62cf9acf00d00dbc02d",
"date": "2222-02-24T00:00:00.000Z",
"description": "22",
"Object1": {
"_id": "5c69a62cf9acf00d00dbc02b",
"date": "2222-02-24T00:00:00.000Z",
"user": "5c30fd5890bbd24a1c46c7ee",
"positionsObject1": [
{
"id": 1,
"Object2": {
"_id":"5c69a62cf9acf00d00dbc02c",
"name": "IWANTALLOBJECTSWITHTHISNAME"
},
"description": "22",
"value": 22
}
],
"id": 13,
"__v": 0
},
"user": "5c30fd5890bbd24a1c46c7ee",
"id": 7,
"__v": 0
}
]
I'm new in mongoDB and this query is really really hard. I tried everything. Thank very much for the help.
You can specify the path using dot notation:
db.col.find({ "objects.Object1.positionsObject1.Object2.name": "IWANTALLOBJECTSWITHTHISNAME" })

MongoDB, remove nested doc in an array

I have the following structure in MongoDB and I try to remove the documents that contains specific tags. I can't seem to be able to get the $pull work.
In this example, I would like to pull the nested doc that has has tags :["BB"]
Any help will be appreciated !
{
"_id": 123,
"socialItems": {
"facebook": [{
"name": "firstFacebook",
"id": 2
}, {
"name": "secondFB",
"id": 43
}],
"instagram": [{
"name": "firstNstagram",
"id": 4
}],
"pc": [{
"name": "firstPC",
"id": 55,
"tags": [
"ab"
]
}, {
"name": "secondPC",
"id": 66,
"tags": [
"BB"
]
}]
}
}
I assume you are trying to drop the nested 'pc' doc, from the array? You also don't mention if you're using a specific driver for this, so I've assumed you're running this in the Mongo shell.
The following will remove documents from the 'pc' property, when containing the 'BB' tag.
db.collectionName.update({'socialItems.pc.tags': 'BB'}, {$pull: {'socialItems.pc': {tags: 'BB'}}})