i have my structure like this :
test{
_id: 60eadb64b72caa2ae419e085,
testid: 'hh',
time: 45,
testPassword: 123,
startTime: 2021-07-11T11:52:04.245Z,
Students: [
{
_id: 60eadb98b72caa2ae419e088,
submission: '#*#org 0h #*##*#ret#*#',
familyName: 'dsc',
firstName: 'ccccc',
group: 2,
time: 0.8772833333333333
},
{
_id: 60eadbb5b72caa2ae419e08c,
submission: '#*#org 0h #*##*#ret#*#',
familyName: 'eqf',
firstName: 'aaaaa',
group: 56,
time: 1.357
}
],
__v: 0
}
i want to get just the object that has the _id: 60eadb98b72caa2ae419e088 from the array of students like this
{
_id: 60eadb98b72caa2ae419e088,
submission: '#*#org 0h #*##*#ret#*#',
familyName: 'dsc',
firstName: 'ccccc',
group: 2,
time: 0.8772833333333333
}
you can search inside array of objects in mongoose like this
db.collection.find({"Students._id": yourId})
you can go as deep as you want
db.collection.find({"Students.users.info.name": username})
and for a single match you can use findOne like this
db.collection.findOne({"Students._id": yourId})
the if you want only the object inside the Students array you can find it by javascript find function
const wantedObject = myObj.Students.find(e => e._id === "60eadb98b72caa2ae419e088")
You can use following aggregate to find you required result, I have tried at my local it is working fine
db.users.aggregate([
{
$match:{
"Students._id":ObjectId("60eadb98b72caa2ae419e088")
}
},{
$unwind:"$Students"
},
{
$project: {
submission:"$Students.submission",
_id:"$Students._id",
familyName:"$Students.familyName",
firstName:"$Students.firstName",
group:"$Students.group",
time:"$Students.time",
}
},
{
$match:{
_id:ObjectId("60eadb98b72caa2ae419e088")
}
}
]);
Related
I have an array I am using to create a put for batchwriteitem.
const people = [{
location: 'London',
name: 'Tony Wilson',
pets: [ {name: 'Cuddles', age: 4}, { name: 'Jess', age: 2}]
},
{
location: 'Manchester',
name: 'Liz Smith',
pets: [ {name: 'Fluffy', age: 4}, { name: 'Keith the cat', age: 2}]
}
]
My batchwriteitem loop is working for individual items
location: { S : item.location },
but when I try and input the pets array as an array it fails
pets: { M: item.pets },
So this all works except the pets array.
const request = pets.map(item => {
const createdDate = Date.now();
return {
PutRequest: {
Item: {
location: { S : item.location },
createdDate:{ N: createdDate },
pets: { M: item.pets }
}
}
});
Do I need to break down the pets array into types and if so how can I achieve this?
Edit
pets: { L: item.pets }, does not work
**Cannot read properties of undefined (reading '0')
and the old syntax without the types does not work on v3 with the document client for me.
Pets is an array, which is also known as a list type. You are setting it as a dictionary/map type as you've set the value to M. It should be L:
pets: { L: item.pets },
I would advise that you use the Document Client as it means you do not need to think about the type conversions, and just use native JSON objects:
pets: item.pets,
I have following data in my mongodb database , how can I write a mongoose query to select a particular object from "cartItems" which is a array of objects and update its "qty" and "price" filed.
Here's the data:-
{
_id: new ObjectId("634a67e2953469f7249c9a7f"),
user: new ObjectId("6348a56590b49a8313d434fa"),
cartItems: [
{
_id: new ObjectId("63494302fc6db508894ba109"),
name: 'Chola Bhatura',
image: 'https://www.indianhealthyrecipes.com/wp-content/uploads/2022/03/bhatura-recipe-680x1020.jpg.webp',
qty: 1,
price: 200
},
{
_id: new ObjectId("634941f3fc6db508894ba105"),
name: 'Poha',
image: 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSuxnPaCuwhqgfnK3DfXFGelvKpfhjyDWpmkQ&usqp=CAU',
qty: 1,
price: 50
}
],
totalQty: 2,
totalPrice: 250,
createdAt: 2022-10-15T07:57:22.941Z,
updatedAt: 2022-10-15T09:57:29.734Z,
__v: 0
}
You can do it with positional operator - $, like this:
db.collection.update({
_id: ObjectId("634a67e2953469f7249c9a7f"),
"cartItems._id": ObjectId("634941f3fc6db508894ba105")
},
{
"$set": {
"cartItems.$.qty": 10,
"cartItems.$.price": 100
}
})
Working example
lets say that you make a call to an API and get back an array of values like this
{
orders: [
{
id: '159151',
owner: 'steve',
created_at: '1662518452935217224',
}
]
}
to pull the id value I would normally write
const id = orders.orders[0].id
. sometimes however I get multiple back at the same time. it ranges from 1 - unknown and need to pull and input all the ids .
{
orders: [
{
id: '159151',
owner: 'steve',
created_at: '1662518452935217224',
},
{
id: '159152',
owner: 'john',
created_at: '1662518628829631781',
},
{
id: '159164',
owner: 'bob',
created_at: '1662519501403450193',
}
]
}
what can you do if you need to pull multiple id values at the same time but your unsure of the amount of id values that will be returned when you make the call to the API?
Assuming all the id keys in your example were the same (rather than idx). How about mapping them to an array?
const response = {
orders: [
{
id: '159151',
owner: 'steve',
created_at: '1662518452935217224',
},
{
id: '159152',
owner: 'john',
created_at: '1662518628829631781',
},
{
id: '159164',
owner: 'bob',
created_at: '1662519501403450193',
}
]
}
const ids = response.orders.map(order => order.id);
const count = ids.length
console.log(ids, count)
Use Array.prototype.map:
const data = { orders: [{ id: 12345 }, { id: 56789 }, { id: 192837 }] }
const ids = data.orders.map(o => o.id)
console.log(ids)
You can simply achieve that with a single line of code with the help of Array.map() method.
Live Demo :
const obj = {
orders: [
{
id: '159151',
owner: 'steve',
created_at: '1662518452935217224',
},
{
id: '159152',
owner: 'john',
created_at: '1662518628829631781',
},
{
id: '159164',
owner: 'bob',
created_at: '1662519501403450193',
}
]
};
const idsArr = obj.orders.map(({ id }) => id);
console.log(idsArr);
Is there a way in MongoDB to get records between a range of numbers?
In my example, I am finding the records that match common: 1, and am using a fake range() function to get only the records between that range. In theory, you could just put any numbers in the range function and it would output the records in that range.
This is not what I am asking: $gte, $gt, $lte, $lt
Note: I am not querying based on values. I am querying based on the records natural position in the filesystem relative to all other records.
Users Collection:
db.users = [{
_id: 123,
name: "Bill",
common: 4
},
{
_id: 456,
name: "Jeff",
common: 2
},
{
_id: 789,
name: "Steve",
common: 4
},
{
_id: 321,
name: "Elon",
common: 3
},
{
_id: 654,
name: "Larry",
common: 1
},
]
Unworking Example: (range() isn't a real function, just used to give an idea)
users.find({common: 4}).range(0, 2).then((users) => {
console.log(users)
})
Expected Result: (because the common fields match and the records are between the range 0 and 2)
db.users = [{
_id: 123,
name: "Bill",
common: 4
},
{
_id: 789,
name: "Steve",
common: 4
},
]
This doesn't give the exact expected result, but the whole idea was to select records between two numbers (eg. a range). The way you do this is with the $skip and $limit methods.
users.aggregate([{$skip: 1}, {$limit: 3}, {$match: {common: 4}} ]).then((users) => {
console.log(users)
})
I have an array of objects containing more objects.
const latestMatchesArray = [
{
team1: {
team_id: '1234',
teamName: 'abc 101',
score: 1,
},
team2: {
team_id: '4321',
teamName: 'cba 101',
score: 0,
},
},
{
team1: {
team_id: '1234',
teamName: 'abc 101',
score: 0,
},
team2: {
team_id: '4321',
teamName: 'cba 101',
score: 1,
},
},
]
Each object contains a match between two teams, after the match, the scores are updated.
Winner gets 1, loser gets 0.
Now I want to filter the array and get only teams with score = 1.
How to do this efficiently?
Not sure if this is what you're looking for, but to get an array of teams that won, you can use Array.prototype.reduce() like this:
const winners = latestMatchesArray.reduce(
(teams, match) => [
...teams,
...[match.team1, match.team2].filter(
team => team.score === 1
)
],
[]
);