Designing a multidimensional array of MongoDB

I just started learning MongoDB and can't find a solution for my problem.

Got this document:

> db.test.insert({"name" : "Anika", "arr" : [ [11, 22],[33,44] ] }) 

Pay attention to the "arr" field, which is a multidimensional array.

Now I am looking for a query that returns only the value arr [0] [1], which is 22. I tried to achieve this using $ slice, however I do not know how to address the second dimension with this.

 > db.test.find({},{_id:0,"arr":{$slice: [0,1]}}) { "name" : "ha", "arr" : [ [ 11, 22 ] ] } 

I also tried

 > db.test.find({},{_id:0,"arr":{$slice: [0,1][1,1]}}) { "name" : "ha", "arr" : [ [ 11, 22 ] ] } 

The desired result will be either

 22 

or

 {"arr":[[22]]} 

thanks


EDIT:

After reading the comments, I think I have simplified the data of the example too much, and I must provide additional information:

  • There are many more documents in the collection, such as I have provided. But they all have the same structure.
  • There are more array elements than two
  • In the real world, an array contains really long texts (500kb-1mb), so it’s very easy to transfer all the data to the client.
  • Before aggregation, I will make a request on the 'name' field. Just skipped this in the example for simplicity.
  • Target indices are variables, so sometimes I need to know the value of arr [0] [1], next time it is arr [1] [4]

data examples:

 > db.test.insert({"name" : "Olivia", "arr" : [ [11, 22, 33, 44],[55,66,77,88],[99] ] }) > db.test.insert({"name" : "Walter", "arr" : [ [11], [22, 33, 44],[55,66,77,88],[99] ] }) > db.test.insert({"name" : "Astrid", "arr" : [ [11, 22, 33, 44],[55,66],[77,88],[99] ] }) > db.test.insert({"name" : "Peter", "arr" : [ [11, 22, 33, 44],[55,66,77,88],[99] ] }) 

Request example:

 > db.test.find({name:"Olivia"},{"arr:"...}) 
+5
source share
2 answers

You can use the aggregation structure:

 db.test.aggregate([ { $unwind: '$arr' }, { $limit: 1 }, { $project: { _id: 0, arr: 1 } }, { $unwind: '$arr' }, { $skip: 1 }, { $limit: 1 } ]) 

Return:

 { "arr": 22 } 

Edit: The original poster changed my mind to fit his needs and came up with the following:

 db.test.aggregate([ { $match: { name:"Olivia" } }, { $project: { _id: 0,arr: 1 } }, { $unwind: '$arr' }, { $skip: 1 }, { $limit:1 }, { $unwind: "$arr" }, { $skip: 2 }, { $limit: 1 } ]) 

This query will result in { arr: 77 } given the extended data provided by the OP. Note that $ skip and $ limit are required to select the correct elements in the array hierarchy.

+2
source

The $slice form you are requesting does not support multidimensional arrays. Each array is considered individually and therefore is not supported in this way by the current $slice .

Thus, in fact, this is done much shorter in terms of indexed “first” and “last” values ​​than was suggested using .aggregate() , and currently:

 db.test.aggregate([ { "$unwind": "$arr" }, { "$group": { "_id": "$_id", "arr": { "$first": "$arr" } }}, { "$unwind": "$arr" }, { "$group": { "_id": "$_id", "arr": { "$last": "$arr" } }} ]) 

But in future releases of MongoDB (currently working in 3.18 development since writing) you have $arrayElemAt as an operator for an aggregation structure that works like this:

 db.test.aggregate([ { "$project": { "arr": { "$arrayElemAt": [ { "$arrayElemAt": [ "$arr", 0 ] }, 1 ] } }} ]) 

Both basically come to the same result { "arr": 22 } , although the future available form works quite flexibly with respect to the array index values, and not the first and last.

0
source

Source: https://habr.com/ru/post/1233326/


All Articles