How to query through nested keys in Google datastore? - node.js

I have users, stored under specific unique IDs. I need to query them by a certain property, but I cannot figure out how to do that when my unique ID is part of the key.
const user1 = {
id: 1,
name: 'John Smith',
cityId: 102,
};
const user1 = {
id: 2,
name: 'Rudy Black',
cityId: 102,
};
const upsertUser = user => {
const key = datastore.key([ 'users', user.id ]);
return datastore.upsert({ key, data: user });
});
const getUsersInCity = async cityId => {
const query = datastore.createQuery('users').filter('cityId', '=', cityId);
const [ users ] = await datastore.runQuery(query);
return users;
};
upsertUser(user1);
upsertUser(user2);
console.log(await getUsersInCity(102)); // Expected: John Smith, Rudy Black

An example of code that you can give it a try using to query values via ID, it's using the below code:
const key = this.datastore.key(['Customer', id:number]);
await this.datastore
.get(key)
.then(results => {
console.log(results);
})
.catch(err => { console.error('ERROR:', err); });
This code was get from the article Google DataStore Query By Nodejs. This article provides some good examples of queries that you can give a look.
I would recommend you to take a look at it and use the above code as a start point.
Let me know if the information helped you!

Related

How to remove a certain position from an array of objects that matches a value in Mongoose?

Is the first time I am working with backend (Mongoose, express, nodeJs). I have a collection of users in MongoDB.
I am sending the favoriteId from frontend and getting it in the backend. I want to delete the position of the array that matches with the favorite Id I am passing to the function.
I have tried several ways to remove the favorite using the $pull operator and the favoriteId but none work. So I don't know how to do it.
I would appreciate if someone could help me.
This is structure in MongoDB:
_id: new ObjectId("63"),
username: 'test1',
email: 'test1#gmail.com',
favorites: [
{
id: '25',
version: 'version3',
team: 'team1',
},
{
id: '27',
version: 'version2',
team: 'team4',
}```
This is my controller function:
```export const removeFavorite = async (req, res) => {
//Here I have the user Id 63
const userId = req.params.userId;
//here I have the favorite Id I Want to remove : 25
const favoriteId = req.body.params.id;
// Here I select the user in the collection
const deleteFavorite = await User.findOne({ _id: userId });
// Here I want to remove the favorite that matches with favoriteId (25)
res.status(200).json('ok');
};```
Try this:
User.update({ _id: userId }, { $pull: { 'favorites': { 'id': favoriteId } } });

Return search result while the user is typing with MongoDB

Create such feature where user can see the results based on the text in the input field
I want to create a feature where user can type in an input field and see the result as the user types. I did implemented it and the code is there below. Now, I know this code is not at all scalable, or even efficient (I am sending DB request on every keystroke). I want to know how I can make this more efficient and possibly scalable.
const search = async (req, res) => {
try {
const input = req.query.text.replace(/ /g,'');
if(!input){return res.end()}
const result = await Promise.all([
User.find({ username: new RegExp(input, "i") }),
Post.find({ description: new RegExp(input, "i") }),
]);
// const users = await User.find({ username: new RegExp(input, 'i') });
res.json(result)
} catch (error) {
console.log(error);
res.status(500).json(error);
}
};

How to add an object to an array of objects in Nodejs?

I'm creating a backend for my React web application and I'm trying to subscribe a user to a match, this match is an object that have an array called "players" and when I click on the join button the username and profilePicture of the user are being dispatched to my backend. The first user info is sent perfectly but when a second user is subscribed the info of the first one is replaced for the second one.
This is my function that push the data:
const playerJoined = async (req, res) => {
const torneoId = req.params.id;
const uid = req.uid;
const profilePicture = req.profilePicture;
const username = req.username;
console.log(req.params);
try {
const torneo = await Torneo.findById(torneoId);
if (!torneo) {
return res.status(404).json({
ok: false,
msg: "Torneo no existe por ese ID",
});
}
const newPlayer = {
profilePicture: profilePicture,
username: username,
};
const nuevoTorneo = {
...req.body,
players: newPlayer,
};
const torneoActualizado = await Torneo.findByIdAndUpdate(
torneoId,
nuevoTorneo,
{
new: true,
}
);
res.json({
ok: true,
torneo: torneoActualizado,
});
} catch (error) {
console.log(error);
res.status(500).json({
ok: false,
msg: "Hable con el administrador",
});
}
};
My frontend is working well because when I added more users the array of objects shows all the players like this:
players: (2) [{…}, {…}]
But on my mongo DB shows only the last user info added like I mentioned before.
I really appreciate any help.
You seem to be replacing the players property instead of pushing into it.
const nuevoTorneo = {
...req.body,
players: newPlayer,
};
When you grab the torneo by id, you should have access to that players property already, so spread that array into your nuevoTorneo as well:
const nuevoTorneo = {
...req.body,
players: [...torneo.players, newPlayer],
};
It is because you always put your newPlayer into the "player" field of your nuevoTorneo and updated the same document. I assume you are using mongoose, You probably should just modify the "torneo" after your query and do something like this:
const torneo = await Torneo.findById(torneoId);
const newPlayer = {
profilePicture: profilePicture,
username: username,
};
torneo.nuevoTorneo.players.push(newPlayer);
await torneo.save();
Or to simply modify your code as:
const nuevoTorneo = {
...req.body,
players: [...torneo.nuevoTorneo.players,newPlayer],
};
I recommend the first method, let me know if you have any questions.

SEQUELIZE: Cant access database of an intermediate table

I am learning how to use sequelize in nodeJS, I really like it but there are some tables that i am not being be able to access, let me show you:
GIVEN THESE ASSOCIATIONS:
Product.belongsTo(User,{constraints:true, onDelete:'CASCADE'});
User.hasMany(Product);
User.hasOne(Cart);
Cart.belongsTo(User);
Cart.belongsToMany(Product,{ through:CartItem});
Product.belongsToMany(Cart,{ through:CartItem});
I am trying to build a controller that post products in the cart, it looks like this:
exports.addToCart = (req, res, next) => {
const ID = req.params.cartProductID;
let newQuantity = 1;
let fetchedCart;
req.user
.getCart().then(cart => {
fetchedCart = cart;
return cart.getProducts({ where: { id: ID } });
}).then(products => {
let product;
if (products.length > 0) {
product = products[0];
}
if (product) {
const oldQuantity = product.cartItems.quantity;
newQuantity = oldQuantity + 1;
...
On this last line, I get an error :
TypeError: Cannot read property 'quantity' of undefined if I log that last product on the console I can actually see this:
id: 1,
name: 'fdff',
description: 'fff',
price: 33,
createdAt: 2020-03-24T17:19:58.000Z,
updatedAt: 2020-03-24T17:19:58.000Z,
userId: 1,
'cart-item': [cart-item]
the question is, what is the correct way to access that 'cart-item' object?
Thanks in advance.
Marc

How to use json object with where clause?

What I'm trying to achieve
Find all players which is in the authenticated users team.
What is the Problem?
Unable to use the returned json within const findUsers = await User.findAll where clause and I am unsure if this is the correct way.
Database Tables
Users Table : id (PK) , etc
Teams: id (PK) , etc
TeamUsers: id , TeamID (Foreign Key) , UserID (Foreign Key) , etc
Returning Json from FindTeamUsers (Var ob) which is correct
[{"id":2,"TeamID":1,"UserID":1,"createdAt":"2019-08-09","updatedAt":"2019-08-09"},{"id":3,"TeamID":1,"UserID":3,"createdAt":"2019-08-09","updatedAt":"2019-08-09"},{"id":76,"TeamID":1,"UserID":5,"createdAt":"2019-08-22","updatedAt":"2019-08-22"}]
Below is the Route that I am currently using using Nodejs, ExpressJS
router.get('/Team', auth, async function(req, res) {
// -- Get the Users team that is currently Authenticated (req.user.id (auth) )
const findTeam = await TeamUsers.findOne({
where: {
UserID: req.user.id
}
});
//If the User has a team
if (findTeam) {
// -- Get the players Team Mates who have the matching TeamID
const findTeamUsers = await TeamUsers.findAll({
where: {
TeamID: findTeam.TeamID
}
});
//Store the object and Display in JSON FORMAT
var ob = JSON.stringify(findTeamUsers);
console.log(ob);
if (!findTeamUsers) {
console.log('error');
} else {
//find the Users Details From the Users Table Model
//findTeamUsers - Is an array of each record found from const findTeamUsers = await TeamUsers.findAll
const findUsers = await User.findAll({
where: {
id: ob.UserID
}
});
res.status(200).json(findUsers);
}
}
});
Your ob is a string so ob.UserID is undefined. findTeamUsers (FindTeamUsers result) is an array of object so findTeamUsers.UserID would be undefined too. (array findTeamUsers does not have property UserID).
You can pass an array of UserIDs to search multiple elements (if you want to find for all UserIDs in the array):
User.findAll({
where: {
id: findTeamUsers.map(o => o.UserID)
}
})

Resources