Get Firestore subcollections without use id - node.js

I have a problem with getting data from the Firestore with a following structure
Here is how I get category collection:
app.get('/getProjectsNo', (request, response) => {
response.set('Access-Control-Allow-Origin', '*')
let orders = []
db.collection('companies').doc('renaultsomaca').collection('orders').get().then(snapshot => {
snapshot.forEach((doc) => {
orders.push(doc.data())
});
response.send(orders)
})
})
It gives me: orders list.But I need to get orders without using doc('renaultsomaca').Because I just need all orders not only renaultsomaca orders.

What you're describing is known as a collection group query, which queries across all collections with a specific name.
To get all documents from orders collections, no matter where they are in the database, you'd do:
const querySnapshot = await db.collectionGroup('orders').get();
querySnapshot.forEach((doc) => {
console.log(doc.id, ' => ', doc.data());
});
There is no way to specify the path to the orders collection, so if you have multiple types of orders that you want to query separately, you'll have to give them distinct names.

Related

Mongoose .find() with unique filter

I have a big DB with some duplicate items. Can I use .find() with filter by unique field? If I use .distinct('term') it return an array of unique terms like ['term1', 'term2', 'term3'], but I want to return an array with entire objects from db, filtered by unique 'term'.
I resolved it by filtering the response from .find()
responses = await Product.find({ product_id: data.input });
let container = [];
responses
.filter((value, index, self) => {
return (
self.findIndex((v) => v.search_term === value.search_term) === index
);
})
.map((ele) => {
container.push(ele);
});

Delay when removing row in postgres with knex

I have a local postgres database running on my machine. I use node.js to access it. I have a table called 'friends' where every row is a user and a friend. I also have a table called 'users' where every row has all basic info about a user(e.g name and such).
When I want to remove a friendship between two users I have to remove two rows from the 'friends' table. I do this with this function:
const removeFriend = async (clientId, friendId) => {
// initiate transaction
return db
.transaction((trx) => {
// remove friendship from client
trx('friends')
.where({ user_id: clientId, friend_id: friendId })
.del()
.then(() => {
// remove friendship from friend
return trx('friends').where({ user_id: friendId, friend_id: clientId }).del();
})
// if all good then commit
.then(trx.commit)
// if bad then rollback
.catch(trx.rollback);
})
.catch(() => 'error');
};
I call the removeFriend function this way removeFriend(clientId, friendId)
Then when i want to get a list of all friends with their names from the database i use this function:
const getUserFriends = async (clientId) => {
// get friends
return db('friends')
.where({ user_id: clientId })
.join('users', 'users.id', 'friends.friend_id')
.select('friends.friend_id', 'users.name')
.then((friends) => friends)
.catch(() => 'error');
};
I call the getUserFriends function this way await getUserFriends(clientId)
The problem is that when I use removeFriend function and then directly use the getUserFriends function i get a list where the users are still friends. However, If i look in the database the rows have been deleted so naturaly i should get a list where the users are not friends. Do I use the await wrong or something?

Firebase Nodejs - after get listCollections

I want to get a collection of subCollections,
admin.firestore()
.collection(SCHEDULE_COLLECTION)
.doc(user)
.listCollections()
.then(collections => {
const cId = [];
collections.forEach(collection => {
});
return res.send(cId);
})
.catch(err => {
console.log(err);
return res.status(500).send(err);
});
I'm getting here ID,
Now I want to get the collections under
this object
How I can do it?
Thanks
Those are not subcollections. What you circled are fields in a single document. Just read build a reference to the document and read it like you normally would with get(). "events" and "foods" will be array type fields in the document snapshot.
const ref = admin.firestore()
.collection(SCHEDULE_COLLECTION)
.doc(user)
.collection(collection)
.doc(...)
.get()
You'll have to query the collection to get the list of documents if you don't know the document ID.

How to send bulk MongoDB count() queries?

My application has a search field and to do an autocomplete, I first fetch the distinct() values, and immediately after, I send a count() query for each distinct value. There can be dozens of values to then count, that's a lot of queries.
Any idea how I could avoid this large number of queries using MongoDB's NodeJS module?
For now, the query is as such:
const baseQuery = {
"organization": organization,
"status": "processed"
}
let domains = []
// A. Query to get the disinct values
MongoDB.getMainCollection().distinct(`location.hostname`, { organization, status: "processed" })
// B. Got the value, now creating a COUNT() query for each
.then(list => {
domains = list.map((host,idx) => Object.assign({}, { domain: host, count: 0, idx: idx }))
const countingPromises = list.map(host => MongoDB.getMainCollection().count(Object.assign({}, baseQuery, { "location.hostname": host })))
return Promise.all(countingPromises)
})
// C. Putting it all together
.then(values => {
values.forEach((count, idx) => {
const domain = domains.find(d => d.idx === idx)
if (domain) {
domain.count = count
}
})
domains.sort((a,b) => b.count - a.count)
resolve(domains)
})
.catch(err => reject(new AppError(`Error listing hostnames for #${organization}.`, 500, err, payload)))
p.s. this works as intended and returns what I want -- just want to avoid so many queries and perhaps bundle them if possible?
You can get all the distinct values and their counts in a single aggregate query:
MongoDB.getMainCollection().aggregate([
// Filter for the desired docs
{$match: baseQuery},
// Group the docs by location.hostname and get a count for each
{$group: {_id: '$location.hostname', count: {$sum: 1}}}
])

How to query for an array of users in my users collection in mongodb using mongoose?

I have a collection of some users (along with their contact numbers) registered in my node and mongodb app.
Now I have an array of contact numbers. I want to get an intersection of this array and the users in my app. How to do it, since I cannot take each number and check for it's existence in the database. Any help/link would be helpful. Thanks in advance.
You can use the $in operator. It would really help if you at least provided some code, like your schemas, previous attempts etc.
Here is an example of how to do ii assuming you are using mongoose, and have a user schema with a number property and an array of numbers.
User.find({ number: { $in: numbers } })
.then(function (docs) {
// do something with docs here;
})
.catch(handleErr);
This can be done simply using promises. I am assuming you have an array of contact numbers and a collection Users which has field contact number. The below function will get you the list of all the Users with contact numbers listed in the array. I am assuming that the User model is available and the contact array is being passed as a function argument. Basically this function will loop through the contact list array and find any user with that contact no in the user collection and return a promise. All the promises are being pushed into an array and the promise will be resolved only when all the async operations have completed resulting in either success or error.
// import User from User-model-defition
function getUsersByContact(contactArr) {
return new Promise((resolve, reject) => {
const data = [];
const errors = [];
contactArr.map(id => {
User.findOne({ contact_no : id })
.then(response => {
if (response.user) { //checking if the response actually contains a user object
data.push(response.user);
} else {
errors.push(response.error);
}
if (contactArr.length === data.length + errors.length) {
//this makes sure that the promise will be resolved only when all the promises have been resolved
resolve({ data, errors });
}
})
.catch(error => reject(error));
})
})
}

Resources