Project elements from Array of Arrays in MongoDB - arrays

I am currently struggling with a search through an array of arrays within a JSON file that is imported into MongoDB compass. At the code below you can see the array "track" contains multiple other arrays. Now I want to get the 4th value of each of this arrays, for example, I want to get "load" from the first, "mouseover" from the second and so on...
{
"name":"nutzer1_50ms",
"ip":"::1",
"date":"Sat, 16 Dec 2017 21:53:19 +0100",
"screen":"1920x1080",
"window":"1920x966",
"document":"1024x786",
"track":[
[1513457569930,0,0,"load",""],
[1513457569953,79,229,"mouseover","p3"],
[1513457570274,79,228,"mousemove","p3"],
[1513457570280,79,226,"mousemove","p3"],
["end","end","end","end"]]
}
I would be very glad to get some help on this :)

You can try below aggregation query.
$map iterating over track values & $arrayElemAt to project the 4th element from array.
db.collection_name.aggregate([
{
"$project": {
"4th": {
"$map": {
"input": "$track",
"as": "track",
"in": {
"$arrayElemAt": [
"$$track",
3
]
}
}
}
}
}
])

Related

MongoDB aggregation for finding an index of array nested object with $gt condition

I am trying to get the positional index of an array element (to push more elements at $position). I'm specifically targeting a single document (say, id=x)
Simplified document:
{
id:"x",
samples:[{"timestamp":123},{"timestamp":234},{"timestamp":345}}
}
Aggregation pipeline:
collection.aggregate([{"$match": {"id": "x"}},
{"$project": {"matchedIndex": {"$indexOfArray": ["$samples.timestamp", 234]}}}])
This works to return matchedIndex=1 .
Now I would like to find the index of 'samples' where timestamp is greater than say 235, which should return '2'
I have tried combinations of:
collection.aggregate([{"$match": {"UUID": "5fd41e35-5e49-O977-t091-6f228bc65e37"}},
{"$project": {"matchedIndex":
{"$indexOfArray": ["$samples.timestamp",
{"$gt": ["$$timestamp", 235]}]}}}])
I understand this wont work, I'm just not sure how to go about it.
The purpose is to insert many elements between timestamps. Maybe there is a better way entirely to do this. Thanks
Instead of using "$samples.timestamp" as first argument you can use $map there to transform it into an array of true and false values depending on your condition, try:
{
"$project": {
"matchedIndex": {
"$indexOfArray": [
{ $map: { input: "$samples.timestamp", in: { $gte: [ "$$this", 235 ] } } },
true
]
}
}
}
Mongo Playground

throwing an error while trying to convert the data types in mongoshell

I created a database named as database and a collection called Netflix. there is a field in the database called "genres" which was of type string I need to change the data type to the array. I am trying to use the below command in the mongo shell but it's throwing an error.
db.netflix.find({}).forEach(function(x){x.genres=JSON.parse(x.genres); db.netflix.save(x); })
**Error:**
TypeError: db.netflix.save is not a function
below pic shows how the data in genres field looks like
Here's one way to let the MongoDB server do all the work by using a pipeline in an update.
N.B.: I have little regex-foo so there is a better regex. E.g., if an element of "genres" (between quotes) contains a comma, the "regex" below won't be sufficient. Also note that I needed to escape " with \ in the "regex" - you may, or may not need to do this.
db.collection.update({
"genres": {
"$type": "string"
}
},
[
{
"$set": {
"genres": {
"$map": {
"input": {
"$regexFindAll": {
"input": "$genres",
"regex": "(?<=\")[^,]*?(?=\")"
}
},
"as": "elem",
"in": "$$elem.match"
}
}
}
}
],
{
"multi": true
})
Try it on mongoplayground.net. (Modified sample document from MongoDB Atlas documentation.)
Starting in MongoDB 4.2, the
db.collection.save()
method is deprecated. Use
db.collection.insertOne()
or
db.collection.replaceOne()
instead.
for the above query , you can try, this works:
db.netflix.find({}).forEach(function(x){x.genres= JSON.parse(x.genres); db.netflix.replaceOne({id:x.id},x); });

Mongoose query penultimate item from array of objects

I have schemas each containing an array of objects looking like this:
{name: String, _id: ObjectId}
Each schemas array has multiple items, I need to match the penultimate (next to last) items _id inside an aggregate function, which currently looks like this:
{ "$match": {$expr: {$gt: [{"$arrayElemAt": ["$path._id", -2]}, mongoose.Types.ObjectId(req.params.id)]}}},
{ "$project": {
"_id": 1,
"name": 1,
"isFile": {
"$cond": [{"$eq": [{"$ifNull":["$data", null]}, null]},false, true]
}
}
}
(the current match function is my attempt, however it does not work)
Any help would be greatly appreciated!
Answer: use $eq instead of $gt...

Mongo find position by id in an Array of Objects

I have a range of documents
{
_id: ObjectId("5e388da4df54cb8efb47e61b"),
userId:'test_user'
productId:'product_6_id'
recommendations:{
_id:123
rankedList:[
0:{id:ObjectId('product_5_id'),Name:'Product_5'},
1:{id:ObjectId('product_6_id'),Name:'Product_6'},
2:{id:ObjectId('product_3_id'),Name:'Product_3'}],
Date:'2020-02-25T05:03:55.439+00:00'
}
},
{
_id: ObjectId("5e388da4df54cb8efb47e62b"),
userId:'test_user1'
productId:'product_3_id'
recommendations:{
_id:123
rankedList:[
0:{id:ObjectId('product_1_id'),Name:'Product_1'},
1:{id:ObjectId('product_5_id'),Name:'Product_5'},
2:{id:ObjectId('product_3_id'),Name:'Product_3'}],
Date:'2020-02-25T05:03:55.439+00:00'
}
}
and I need to find each time the position of productId within the Array of objects rankedList.
Thus here the answer would be positionIndex=1 for first doc and positionIndex=2 for second document.
I am quite confused with $indexOfArray and how I should use it here with aggregate.
Yes, you need $indexOfArray. The tricky part is that recommendations.rankedList is an array of objects however MongoDB allows you to use following expression:
$recommendations.rankedList.id
which evaluates to a list of strings, ['product_5_id', 'product_6_id', 'product_3_id'] in this case so your code can look like this:
db.collection.aggregate([
{
$project: {
index: {
$indexOfArray: [ "$recommendations.rankedList.id", "$productId" ]
}
}
}
])
Mongo Playground

MongoDB Update a value from Object in Array in Object in Array

i want to update the value. The gap should be located with his id and the id from the pocket.
I tried with the updateOne() function but i could not find the path vor the gap.
Maybe you can help me.
There will be more objects in the pockets and gaps arrays.
{
"_id":"5a4f535f4dc4b200d43cf333",
"id":"A07","name":"name",
"capacity":"230",
"free":"230",
"open":false,
"location":
{
"longitude":51.02274,
"latitude":7.5612
},
"pockets":
[
{
"id":"A",
"description":"Parktasche",
"capacity":12,
"free":11,
"gaps":
[
{
"id":"7",
"value":true, <-- should be updating
"deployee":false,
"disabled":false,
"guest":false,
"pid":"A"
}
]
}
]
}
If I remember correctly, you need something like pockets.$.gaps.$.value
https://docs.mongodb.com/manual/reference/operator/update/positional/#update-documents-in-an-array

Resources