Should I build one or two mongodb models? - node.js

I am building a mean stack app allowing people to read and write reviews about products.
Reviews will be classified by products on the website : A user will open the page displaying the list of products reviewed on the website and see the name of each products. When clicking on a product, the user is directed to a new page displaying all the reviews about the product.
I was set on building just one model gathering all reviews :
var ReviewSchema = new mongoose.Schema({
productName: String,
productCreator: String,
review: String,
upvotes: {type: Number, default: 0},
author: String
});
The page listing all products would get all reviews from the data base and then only display the productName and productCreator after eliminating all duplicates.
{{productName}} - {{productCreator}}
But it's probably not efficient at all. Would it be better to build two different models, one for the reviews and one for the products ?
I'm sorry if my question is stupid but I'm still learning about MEAN and don't know much about non-relational db, that's my first project ;)

I have built two models that I have embedded. It takes a little more time when writing all the rest routes, but it will simplify both the back and front in the end.

Related

Looking for Mongoose Schema suggestions for individual models

I am in the process of developing a REACT app that would allow a user to find a plant based on their homes environment (long term goal). For my MVP I want to have the user create an account, name their home, add individual rooms with lighting conditions and add plants to each of those rooms. In the event the user does not create any rooms the plants would just sit under their home rather than a specific room by default.
I am struggling on how to design my models and am looking for some suggestions. This will only be my second project on my own so my experience is quite limited.
Currently I have the following models; (attached is a screenshot of each of these models)
plantScheme w/ commonName, scientificName, lightLevel, careLevel, waterReq, etc - This will be seeded with around 100 of the most common household plants to begin with and I intend to use the database to display varying plants on the site whether or not a user is logged in. I also want to link these plants to a specific user when the plant is added to their home.
userSchema w/ username, email, password, home { type: String, required: false, default: 'My Home' } (This begins with where I am open to suggestions. I am not sure if this is the most effective way of establishing the users home), rooms: [ Room.schema ] (pulls from a separate model), plants: [ UserPlant.schema ] (also pulls from a separate model to keep track of plant IDs and room IDs I THINK - haven't tested yet)
userPlantSchema w/ plant_id: { type: Schema.Types.ObjectId, ref: 'Plant', required: true } and room_id: { type: Schema.Types.ObjectId, ref: 'Room', required: false }
and lastly..
roomSchema w/ roomName and lightLevel
If there is a better way of setting up these models and/or keeping track of the users plants I would greatly appreciate the help. Thank you for your time.
screenshot of each model and their established relationships

Node/MongoJS normalization query - how do I translate ID to name?

I'm fairly new to Mongo, and the documentation is still a little blurry for my understanding.
I'm working on a pharmacy app - where doctors are connected to practices. (medical practice) The details (name, address, etc.) of these practices can be changed at any given time, and so I cannot create the doctor in this format:
{ name: "Dr. John", practice: "Yellow Medical Centre" } - because if that name is changed, it will be a pain updating it everywhere.
Now, my question is, assuming that I am already inserting doctors with a practice_id field instead of a practice_name field - how do I resolve the practice_id into a practice_name, before sending it back to the client - because they would like to see the doctor's practice name, not the ID of it.
(I made a huge mess, initially, so I'll just leave the plain part here)
app.get('/doctors', function(req,res){
db.doctors.find().forEach(function(err,doc){
});
});
Am I supposed to loop through them all, or not? Mt goal is for each Doctor's->practice_id to actually contain practice_name - which obviously requires the assistence of the db.practices collection. But how do I make that translation in this stage? Or am I supposed to do it from the client-side controller?
Some guidance would be helpful, thanks.

filter/search function in meteor

I'm looking to implement a search/filter function. It will use a drop down bar as its inputs (so we the user chooses from a set of options).
How my system works now is this: There is a Meteor.users collection, and an Instruments collection. Basically, each user has a list of instruments he plays (for example, Bob plays piano and violin, Alice plays the piano and the flute). In this case, there are 4 objects in the Instruments collection:
1) type: Piano
owner: (bob's ID)
2) type: Violin
owner: (bob's ID)
3) type: Piano
owner: (Alice's ID)
4) type: Flute
owner: (Alice's ID)
So what I'm trying to do is, when I choose "piano" on my drop down list, and then click search, I want it to display Bob and Alice's profiles. I guess this should be done using Meteor's publish feature, but just not sure how to do it (I'm a beginner here).
For example, if how do I tell that specific publication to run when I hit search? I see examples of people setting publish rules to only publish the subset they are searching for, but how do we tell it when to happen? Do we use another template for that so that when we click "search", the URL path changes and thus a different template?
To be clear, my question is just how should I go about doing this. Thanks!
To make it easy, try to bind the instrument ID in Person's Collection as Array,
[{
_id: 'BoBId',
Instrumets: [PianoId, ViolinId],
},{
_id: 'AliceId',
Instrumets: [PianoId, ViolinId],
}];
now you could find any profile, who has the instruments
Person.find({
Instruments:{
$in:[InstrumentsId]
}
});

FourSquare venue search using categories

I am seeing some weird behaviors when I use the search API from FourSquare. The site I am building lists all the nightclub spots (www.nationalvip.com)
When I search using 5 categories:
// 4bf58dd8d48988d121941735 - lounge
// 4bf58dd8d48988d11f941735 - nightclub
// 4bf58dd8d48988d1e7931735 - jazz club
// 4bf58dd8d48988d1e9931735 - rock club
// 4bf58dd8d48988d1d8941735 - gay clubs
Some of the nightclubs that are in category: 4bf58dd8d48988d1d8941735 do no show up.
So query like this:
/v2/venues/search?categoryId=4bf58dd8d48988d121941735,4bf58dd8d48988d11f941735,4bf58dd8d48988d1d8941735,4bf58dd8d48988d1e9931735,4bf58dd8d48988d1e7931735&ll=47.6097,-122.3331&radius=10000&intent=browse&v=20120801
Omits this venue:
https://foursquare.com/v/last-supper-club/40b13b00f964a520a7f61ee3
When I just use that category on it's own they do.
...?categoryId=4bf58dd8d48988d1d8941735&ll=47.6097,-122.3331&radius=10000&intent=browse&v=20120801
I have tried re-arranging the categories. I'd really like to avoid having to call the API many times with various categories.
Has anyone else seen this happen?
Your problem is with the location. The ll param you provided is for a location in San Francisco, but the venue you expect to appear is located in Seattle.
you can increase limit upto 100
I have done that and radius upto 100000meters(100km)

CouchDB a real world example

Tonight in my daily tech Googling I came across couchDB, after seeing tons of presentations about how it perform ten to hundred times better then any RDBM, how it would save us from SQL languages, tables, primary keys and so much more. I decided myself to try it myself. Only problem it seems I am unable to figure out how it works.
Like for a start I would like to code a web contact manager using couchDB. The project would enable user to do basic stuff like
Create/ Edit / Delete contacts
see a list of their contact ordered
search them on various criteria
So how do I start ?
Here some of my thoughts
create a database per user like July, Ann
in those DB, add some document with type contact, the document would look like this at first place see code 1
create / edit / delete is straight forward just need to do the PUT, POST, DELETE in the good database
searching would be handled by couchdb-lucene like dnolen suggested
now here come the difficult part, I don't really understand the whole map/reduce concept and how I can use that to do the jobs I used to do with SQL. Also with views how do you handle paging, also grouping.
I would like to build a screen with a paging set of links something like this
John, Doe
Johny, Hallyday
Jon, Skeet
A B C D E F **J** etc .... <-- those are link to see persons with that first name
what view should I create to achieve that, if you can provide samples it would wonderful.
Contact document.
{
type: 'contact',
firstname: 'firstname',
lastname: 'lastname',
email: ['home': 'foobar#foobar.net', 'work': 'foobar#foobar-working.net'],
phone: ['home': '+81 00 0000 0000'],
address: []
... some other fields maybe ...
}
The upcoming book by O'Reilly is free to read online:
http://books.couchdb.org/relax/
Just install and play around - you can do straight http requests using curl on the command line, or use the built-in web interface called futon.
Storing and retrieving data is really easy, the hardest part is thinking in terms of map/reduce-views instead of sql queries.
IBM has a great tutorial, making use of curl to read/write via the REST interface.
Your application is quite easy to do with CouchDB. You would have a database per user. Contacts are simply documents in a particular user's database. CRUD is just talking to the database using HTTP. You could create views that emit keys (last name, first name) to allow for sorting.
For powerful search I would recommend couchdb-lucene.

Resources