Meteor: how to sort users by most following? - javascript

welcom ...
I have in my Meteor project 2 collections
1 - followers
"_id": "_id",
"follower": "username1",
"following": "username2"
}
2- users
"_id": "_id",
"username": "username",
[...]
}
I would like to sort users by the most following how I can do this
can anyone help me ?....

I would suggest putting the 'followers' collection as an object inside each 'users' document. There's no point in putting them in separate collections and then having to reference back and forth based on a user's ID. It's just taking up more space in your DB. Just make an object inside each user called 'follows' or something similar with the same structure (though make 'follower' and 'following' arrays). Something like this:
"users":{
"_id":_id,
"username":"username",
"follows":{
"followers":["username 1","username 2"],
"following":["username 3", "username 4"],
}
}
Once you have it so each user document has it's own 'follows' object, you can sort users by using the 'aggregate' functionality MongoDB Aggregate. This following code sorts based on the length of the followers array. You'd do a separate one for 'following' swapping out '$followers' with "$following".
db.users.aggregate(
[
{
$project: {
"length": { $size: "$followers" }
},
{ "$sort": { "length": -1 } },
}
]
)
This will probably require some tweaking, of course. just helping lead you in the right direction.

Related

For Prisma Client join queries is it possible to move deeply nested fields to top level of result?

Does Prisma have the ability to move nested fields from another table join to the top level of the result, like a flattened view? I want to put the result JSON into a frontend table without digging through nested objects and building another object.
For example I want to replicate this behavior where I can pick and choose the columns from different tables (columns from User, and School). Currently I use a raw query with a similar SQL, however I wonder if it's possible with using only the Prisma API:
SELECT
u.id
, u.email
, s.school_name
FROM "User" AS u
JOIN "UserSchool" AS us ON us.user_id = u.id
JOIN "School" AS s ON s.id = us.school_id
id | email | school_name
123| student1#email.com | mount high
I want JSON that looks like this:
{
"id": "1",
"email": "student1#email.com",
"school_name": "mount high",
}
If I did this in Prisma, I would need to go into several levels of nested objects to get the same column name on another table for e.g. user[user_school][schoo][school_name]. This requires extra work to loop through all my results, extract from the nested object, and build another object. This example isn't too bad, but I have more joins and deeply nested objects for my actual problem (lots of association/lookup tables). I've experimented with the select and include for my joins, but they are structured with the nested JSON.
users = await prisma.user.findMany({
include: {
user_school: {
include: {
school: true,
},
},
},
{
"id": "1",
"email": "student1#email.com",
"user_school": [
{
"id": 1,
"user_id": "1",
"school_id": "1",
"school": {
"id": 1,
"school_name": "mountain high",
}
}
],
}
It's not possible to flatten out the results as of now.
The only way to achieve this would be by using rawQuery as you mentioned.
However, there is an existing Feature Request which discusses Flattening out the results by providing an option of flatten:true. If you could mention your use case there and add a comment it would help Prisma's Product and engineering team in prioritising it.

Pull a full object from one value

I'm working on a ticket system, and I want to make a close ticket system, that will remove the ticket from the user, so I have my mongo array looking like this
{
"tickets": [{
"id": "cxZgqey2",
"subject": "fdgfdgdfgfdgfd",
"message": "gfdgfdgfdgdfg",
"ownerEmail": "soenmtherhg#gmail.com"
},
{
"id": "r4r-CnIC",
"subject": "dfdsfdsfsdfdsfdsf",
"message": "dsfdsfdfsdfdsfdsfdsfdsf",
"ownerEmail": "soenmtherhg#gmail.com"
}
]}
and I wanted to remove the entire object using only the id, how would I do this? (Using the npm module (not mongoose))
You can use the filter function in arrays and delete it passing the relevant id for that and also you can check loadash.

Limit length array-type of property in Loopback 4 query?

I've been trying this new framework Loopback 4 and its awesome but I dont know to which point is flexible,I'm having the following model on the database:
{
"id": "string",
"lastUpdate": "2020-10-01T18:10:46.306Z",
"name": "string",
"logo": "string",
"data": [
{}
]
}
And what I'm trying there is to make a query that returns me the data, but as is an array, it has a lot of data and I would like to paginate it, so I thought on limiting the query. I've achieved a query to look like the following:
{
"offset": 0,
"limit": 10,
"skip": 0,
"where": {
"name": {"eq":"BengalaSpain"}
},
"fields": {
"data": true
}
}
I'm trying to limit the data property to 10, but of course, this dosnt affects the property itself, just the wrapper object around it. Is there any way to achieve what im trying?
Thanks in advance guys!
LoopBack 4 filters apply at a Repository level as these constraints are passed to the ORM datasource connectors to be converted into their respective native queries (e.g. TOP 10 for SQL Server).
A possible solution is to link the data field into a Relation. Relations essentially create nested Repositories (e.g. hasManyRepository), hence are able to meet the requirement of isolating data into its own Repository.
To quickly create a relation, remove the property from the Model and re-create it using lb4 relation command.
From there, it would be possible to take advantage of the now-enabled InclusionResolver and write use query:
{
"where": {
"name": {"eq":"BengalaSpain"}
},
"fields": {
"data": true
},
"include": [
{
"relation": "<relation name here>",
"scope": {
"limit": 10
}
}
]
}
A side-effect is the separation of data into its own table. However, this should be done irregardless due to database normalization.

MongoDb: Find the generated id of the inserted child on parent save

If I have a document representing a post with comments that looks like this:
{
"_id": "579a2a71f7b5455c28a7abcb",
"title": "post 1",
"link": "www.link1.com",
"__v": 0,
"comments": [
{
"author": "Andy",
"body": "Wish I had thought of that",
"_id": "579a2a71f7b5455c28a7abcd",
"upvotes": 0
},
{
"author": "Jim",
"body": "Just a comment",
"_id": "579a2a71f7b5455c28a7abcc",
"upvotes": 0
}
],
"upvotes": 5
}
In the calling (javascript) code, I add a new comment, by pushing to the post.comments array, then save the post using .save with a callback. In the save callback, I want to get the generated _id of the new comment I just saved. How do I do this?
I've got the parent post document in the callback, of course, but that's not useful as I can't tell which comment was just inserted.
Is there another document method or an alternate form of the .save callback to deal with my situation?
Or do I have to just follow what I'd usually do and generate a unique id on the comment myself before the save?
EDITED: I'm using Mongoose, sorry, forgot to say!
You did not specifically tell, but I assume you use Mongoose because standard MongoDB will not add an _id property to subdocuments.
As mentioned in the Mongoose documentation regarding adding sub-documents, you can use the following code example:
var Parent = mongoose.model('Parent');
var parent = new Parent;
// create a comment
parent.children.push({ name: 'Liesl' });
var subdoc = parent.children[0];
console.log(subdoc) // { _id: '501d86090d371bab2c0341c5', name: 'Liesl' }
subdoc.isNew; // true
parent.save(function (err) {
if (err) return handleError(err)
console.log('Success!');
});
Instead of parent.children[0] you have to use parent.children[parent.children.length - 1] to access the inserted element, though.
I'd assume the item you pushed on the array would be the last one, but that wouldn't work in a multi user system.
Also you could make a comparison against the author and comment fields, though this seems like a lot of trouble, and with just the author and the comment text, you might not be assured a match.
Finally, you could also create the object id and assign it to the comment, then save it. You do that like this:
var mongoose = require('mongoose');
var id = mongoose.Types.ObjectId();
That's what I would do.

couchdb views tied between two databases?

Say I have several databases on my couch instance (in my case a user account database and login session database) The sessions have fields corresponding to a field in the user database. Is there a way to create a view, or make a call that encompasses this correlation, or would it just have to be done with an external script? To be more clear, here's an example.
Account db:
{
"_id": "78555fdfdd345debf427373f9dfaeca4",
...
"username" : "bob"
}
Sessions db:
{
"_id": "78555fdfdd345debf427373f9dfcd7ae",
..
"accountId": "78555fdfdd345debf427373f9dfaeca4",
"username": "bob"
}
Can I use emit or something like that to bundle together all this information in one call?
No, however a common workaround is to have a "type" attribute for documents.
For example...
Application db:
{
"_id": "account.78555fdfdd345debf427373f9dfaeca4",
"type": "account",
...
"username" : "bob"
}
{
"_id": "session.78555fdfdd345debf427373f9dfcd7ae",
"type": "session",
..
"accountId": "account.78555fdfdd345debf427373f9dfaeca4",
"username": "bob"
}
And then in your views:
map:
function (doc) {
if (doc.type=='account') {
# ...
}
}
No, unfortunately there is no way to connect data from multiple databases.
Each view is supposed to be self-contained, otherwise updating any document in 1 database will immediately need to trigger views indexes in every other database to be recalculated in all cases.

Categories

Resources