I would like to know how I can access the elements of an array in mongo (version 3.0) by position, just as I would with $arrayElemAt in the newer versions.
UPDATED: I want to achieve the same of this example using mongodb 3.0:
Thank you very much.
In this case $arrayElementAt returns only one element from a given position. If you want to manipulate a chunk of items you want to return you should use $slice. Please check the link for more references: MongoDB $slice
{ $slice: 3 } //for the first 3
{ $slice: -3 } //for the last 3
{ $slice: 2, 3 } //for 3 elements after skiping the 2 frist
Related
This question already has answers here:
Lodash, find indexes of all matching elements
(6 answers)
Closed 1 year ago.
I have a react js app and using lodash to search thru a collection array which has subarray to find a value like myId:4, the structure looks something like this
myList: [ {
id: 0,
rows: [{ status: [{value: 3}]
},
{
id: 1,
rows: [{ status: [{value: 1}]
}
]
I want to search all the status subarray for value:1
I tried using using _.findIndex and _.find like
_.findIndex(myList.rows, {value:1})>= 3
_.find(myList.rows, {value:1})
Both return the 1st match but not all the matches
After playing with find and findIndex it only finds the first record but not all the records.
Is there a lodash call like findAll? or is there a way to sum up all the subarray record count with that value I am searching for.
Thanks
Found this at another post: Lodash, find indexes of all matching elements
.map(.keys(_.pickBy(Animals, {Id:3})), Number)
I'm currently working on a function which generates an mongodb modifier object based on an orginal object and an changed object.
The goal is to update the document as carefully as possible. (only changes will be added to the modifier)
Changed objects (which may be nested) work just fine. But I'm having issues with arrays:
If I take an array [1,2,3,4] and run arr.splice(1,1), the array looks like this: [1,3,4]. This is correct.
The problem is the following:
When I compare [1,2,3,4] to [1,3,4] my function would change the indexes 1 and 2 and then remove the 3rd index since its not needed anymore.
The generated modifier would look like this:
//document in collection
{
arr: [1,2,3,4]
}
//generated modifier
{
$set: {
'arr.1': 3,
'arr.2': 4
},
$push: {
$slice: 3
}
}
This produces the following error:
MongoError: Cannot update 'arr.1' and 'arr' at the same time
Do you have any suggestions how to remove this last index within one query?
Or do I have to use multiple updates to archive this?
I have mongodb data model where I have some array fields that contain embedded objects or arrays. I have some inconsistencies in the field in question because I've tweaked my application logic. Initially, my model looked like this:
Initial Setup of Results collection
"competition" : "competition1",
"stats" : [
{
"stat1" : [],
"stat2" : []
}
]
However, I saw that this wasn't the best setup for my needs. So I changed it to the following:
New Setup of Results collection
"competition" : "competition1",
"stats" : [
{
"stat1" : 3,
"stat2" : 2
}
]
My problem now is that documents that have the initial setup cause an error. So what I want is to find all documents that have the initial setup and convert them to have the new setup.
How can I accomplish this in mongodb?
Here is what I've tried, but I'm stuck...
db.getCollection('results').find({"stats.0": { "$exists": true }})
But what I want is to be able to do something like
db.getCollection('results').find({"stats.0".stat1: { "$type": Array}})
Basically I want to get documents where the value of stats[0].stat1 is of type array and override the entire stats field to be an empty array.
This would fix the errors I'm getting.
$type operator for arrays in older versions works little differently than what you might think than $type in 3.6.
This will work in 3.6
db.getCollection('results').find( { "stats.0.stat1" : { $type: "array" } } )
You can do it couple of ways for lower versions and It depends what you are looking for.
For empty arrays you can just check
{"stats.0.stat1":{$size:0}}
For non empty arrays
{"stats.0.stat1": {$elemMatch:{ "$exists": true }}}
Combine both using $or for finding both empty and non empty array.
For your use case you can use below update
db.getCollection('results').update({"stats.0.stat1":{$size:0}}, {$set:{"stats":[]}})
This question already has answers here:
How to Update Multiple Array Elements in mongodb
(16 answers)
Closed 5 years ago.
the document model I'm using is as follows.
{
"_id" : "a301c595-f6f3-4ede-91c5-f1cabd548338",
"UserName" : "3#3.com",
"Revision" : 6,
"UserVocabs" : [
{
"Vocab" : "apple",
"LearnStatus" : 0,
"lastChanged" : 213232
},
{
"Vocab" : "book",
"LearnStatus" : 0,
"lastChanged" : 213132
},
]
}
I'm trying to add or replace objects in the UserVocabs array by their Vocab field so I don't know their indexes. till now the only solution I used is to first pull the object and then trying to push its updated version back in the array. but it needs 2 query for each object updates. is there any better solution out there?
You could update one of the elements of array by its index like
db.test.update({"_id": "a301c595-f6f3-4ede-91c5-f1cabd548338"},{$set:{"UserVocabs.1.Vocab":"orange"}})
Or if you want to modify all the elements you could replace the 1 with $ which is a wildcard of an arbitrary index. (you may have to set the last two parameters tags to make this work though)
and could extends the array with
db.test.update({"_id": "a301c595-f6f3-4ede-91c5-f1cabd548338"},{$addToSet:{"UserVocabs":{"key1":"value1","key2":"value2"}}})
Removable of elements could ref to this answer
If you want to use the value of array to find the elem to replace you could:
db.test.update({"UserVocabs.Vocab": "apple"},{$set:{"UserVocabs.$.Vocab":"orange"}})
based on this question...
I am trying to make an aggregate function and filter my array based on values in subarray. Currently my array structure is as follows:
'id':1,
'data': {
'value':1
}
'id':2,
'data': {
'value':1
}
'id':3,
'data': {
'value':2
}
So I need to get all items where data.value is 1. Currently in order to do this I have to do the following:
db.ids.aggregate([
{$match:{id:{$exists:true}}}, //some more matching conditions here...
{$unwind:'$data'},
{$match:{'data.value':1}}//need to get rid of this and move it to the first $match
So the question is can I get rid of the second $match and put my subarray filter condition into the first match? I tried to do that but it did not work and returned the whole document. I really need to filter my array based on subarray value because my db would become very large and I dont want $unwind on the whole bunch of documents.
Thank you.
You could add multiple conditions in the first match itself.
db.ids.aggregate([
{$match:{id:{$exists:true}, "data.value": 1}}
])
and then do your unwind.
try below:
db.ids.aggregate([
{$match:{id:{$exists:true}}, 'data.value':1},
{$unwind:'$data'}