How to design the schema for an author/user model in mongodb - schema

I have looked through most of the mongodb schema design articles on mongo's website and most of the questions here on SO. There is still one use case which I haven't figured out. When looking at these tutorials, they usually reference the article comments problem and the products/categories problem. I want to figure out how to model the one to many relationship (author to posts) when querying a list of posts. Here are the example schemas:
Users: {
_id: ObjectID
Name: String
Email: String
}
Posts: {
_id: ObjectID
user_id: ObjectID
body: String
comments: [
body: String
]
}
Now, lets say you want to run a query for the latest 10 posts. A pretty simple query, but now you have posts with the possibility of each one having a unique ObjectID pointing to the user. Now, how should you accomplish getting the name and email of each user for a post.
Should you create an array of the user ObjectID's from the posts query and then run the query db.users.find({ _id: {$in: PostsUserIDArray}}); After that would you use your application logic to match the right user information to the correct post?
Should you keep a copy of the data in posts. I.E. keep the user ID, name, and email in the posts table. Then just have a hook when a user updates this information to update all the information in posts.
An option which myself or my friend have not thought of.
I appreciate all help as I try to wrap my head around mongo data modeling.

For a few videos I have seen from MongoDB creators, they advocate the second solution. If your user have more data than just a name and email and if you display only name and email when displaying apost, then it's not really bad to store it in the post. Thus you don't have to perform others queries when querying for posts. And since a user doesn't normally change his name every day, it's more effective to run an update to all posts once he changes his name than perform other queries to retrieve informations when displaying posts.
Edit : link to a video http://lacantine.ubicast.eu/videos/3-mongodb-deployment-strategies/

Related

How can I interrogate user activity in Laravel

I'm looking for a way to best analyse the user data in our app.
for example
how many users have read 0 articles on our site
how many users have read 1 article on our site etc
we have a users table with id, username columns and we also have an activities table that creates an entry when an article is viewed. For example it would create a database row with
id
activity
user_id
1
read
1
all of the data we need is there, I just don't know how to interrogate to give that detail.
I personally would use an int code for activity and not a string. So "read" would = 1, "edit"=2...etc If you have no care about what user read with no association, that becomes easy by just setting a flag on the article that was read by article id. So your article table would have:
id article_id activity user_id
1 5 1 8675309
From there just do an eloquent query on article_id where activity = 1...
$articlecount = Article::where('article_id', $request->id)->where('activity', 1)->count();
$articlecount will give you all of the reads for that article.
If you need it based on user you could do a one to many relationship from your users models to articles models. Then query the user with(articles). That will bring back all the articles where that user has activity. You could also specify in your eloquent to only bring back activity of reads/edits..etc too. In the same respect you could do the reverse and query the article and see all the users that have read that same article.

Nested Queries in React Admin

How can we possibly use Nested Queries? It just seems like a big waste when my server fully supports nested queries.
I'm also unable to make a nested input form.
I have a book, that has an author, and the author has a username with a first name and last name.
When creating the book, I want to show a list of Authors, but the optionText needs to be the author's user's first and last name.
I've been trying to figure it out but figured I'd post here since I've had no luck.
Schema:
Book {
id,
author_id
}
Author {
id,
user_id
}
User {
id,
name
}
In this case, When I want to create a new book (SelectInput), I want to show the Author's first and last name (which comes from their user) in the input.

Sequelize - Incorporate stores into retailers after obtaining the latter

I'm really new to Sequelize and I find the Docs confusing especially for my case since I already had a Postgres DB set up and used sequelize-auto to create all the models from the existing DB.
Now I have the following:
Retailers
Stores
Stores have a FK in retailer_id since Retailers have several Stores, but a single Store belongs to a single Retailer.
I want to retrieve from my Node API a JSON with the following format:
[{
id:"1",
name: "RetailerName",
stores: [{
id: "1",
name: "StoreName",
...
}]
}]
I was thinking of getting all of the retailers, iterate through them and getting all stores based on the "current" retailer id and adding them to retailers, replying that.
However this is not possible without a promise of some sort and since there are better tools to achieve this with sequelize I would like to know how to do this!
Use sequelize's associations (One-To-Many in this particular case)

How to allow a related model in Yii to be empty

In my Yii application I have a pretty simple model setup. I've used the gii autogenerated code to create the basic CRUD, while I get the data for my app in place.
So, I have Authors, and Books. A Book belongs_to an Author.
I have a huge list of books already to enter - but as I haven't entered the Authors yet - none of my books will save, as I keep getting "Trying to get property of non-object" when I save without selecting an author- despite not making Author "required".
As I haven't got my list of books organised by author (it's a straight list of titles in a CSV list) this is preventing me saving any Books.
How can I make the Author optional?
Within the 'rules' function of the Book model you should see something like this:
array('...','...','author', 'required'),
All you have to do is delete the 'author' property from the array, so it will no longer be required. Of course this will only work if the 'author' column in the Book table of the DB is marked as not-required.
I hope it helps you, but I'm afraid it won't solve your problem. The error message you're getting, "Trying to get property of non-object", suggests that you have another problem rather than a not-set required property in a submitted form. If it is the case, you may post the BooksController's "create" function and the associated "_form" view in order to determine what's going wrong.
you could import your authors first, but this would probably wouldn't work either since your csv won't have the author_id in it
if i were you i would delete the foreign key (not the author_id field, just the fk) and import my books, then add authors and when done add the foreign key again to ensure data integrity and use it in the future
Yii won't complain if you do that
So the answer was more simple than I realised - I had the wrong relationship. Instead of a "belongs to" I needed a "has one". The has one relationship allows for nulls.

Organising resource (URI) in REST API

Scenario 1
In my web application say for there is a screen for adding an employee to system. As soon as user tabs after entering name of the employee, it generates the employee code automatically (which is the next field) based on some logic and already present records in the database.
Now I want to expose rest API for this application so that third party devs can build on top of it. So, I will have a resource called as /Employee which will respond for GET, PUT and DELETE verbs. But when a client needs to autofill the code, which is a GET operation, it will be on what resource? Should I make a new resource /EmployeeCodeFor/{Name} or I should get it on /Employee/{Name}/GenerateCode? If I go with /Employee/{Name}/GenerateCode then what about my resource to GET, PUT and DELETE for Employee i.e. actually /Employee/{Id}?
Scenario 2
Here lets take the case of a stackoverflow post. So lets say the resource would be /Post/{Id}. In the same way as in the previous example it lists me possible duplicate question as soon as I tab out of the Title field.
Again on what URL I should get those possible duplicates?
I can't think of more scenarios just now. But many such kind of scenarios may come up in real life application development. How to implement them in RESTful way?
Update on scenario 1
Code and Id are two different fields. Id is primary key, code can be duplicate across departments just to illustrate. Also to generate a code, name should be provided first. So, if user types a name "FirstName LastName" then server might generate FL003 as code assuming that there are already two more employees with firstname starting from F and lastname starting from L in the said department. Department can be identified based on the logged in user.
One way to allow the server an opportunity to pre-fill a bunch of elements in a new resource is to do
POST /Employees
{with empty body}
=>
201 Created
Location: http://example.org/employee/3443
<Employee Id="3443">
<Code>E1001</Code>
<FirstName></FirstName>
<LastName></LastName>
</Employee>
This gives the server one chance to provide default values. If you are looking for a more interactive way for the server to provide feedback during the input, I have another approach but it will take quite a bit more explaining.
Scenario 1
Let say your employee code is a unique identifier. In this case, to get it, you would allow the user to complete any field for the new employee and then make a POST. The server would generate the code and respond to the POST with a link to /Employee/{generated_code} which is the record for your newly created employee.
A GET on /Employee would return a list of all employees. A GET on /Employee/{a_code} will give you the employee detail.
Scenario 2
You could have some kind of query on the /Post collection like /Post?title_like={question_title}. A GET /Post?title_like=REST How to would return you a list of all questions containing "REST How to".