Neo4j newbie here.
I have a graph database with node as Person, edges between nodes are relationship POSTED, POSTED has property "message", now I would like to return relationship with certain message. I wrote query like:
MATCH (ppl) -[p:POSTED]->(s)
WHERE p.message = "How are you?"
RETURN p
It returns nothing.
What is the right way to make relationship queries?
Can I make some queries like:
MATCH (a) -[:KNOWS]->(ppl),
(ppl) -[p:POSTED]->(s)
WHERE p.message = "How are you?"
RETURN p
Creating a lot of same Relations between two nodes is not a good idea if you want to create something like a chat.
In fact, it'll be a lot more easier and faster to create a model like this:
(:User{Foo:"Bar})-[:POSTED]->(:Message{content:"Hello World"})-[:SENT_TO]->(:User{Foo:"blabla"})
This way, you'll be able to store way more thing in your messages and It's easier to do operations with nodes.
You can check this reddit topic to find out the best practices to do what you want.
Related
i wanted to get your expert opinion about this dilema chosing bewteen JSON or Pivot Table
Let just say we have 2 tables here
people
jobs
A person may have multiple jobs, alas, a jobs might have multiple person subscirbed to it.
What is the best approach to it?
Method 1: JSON
I would have jobs column in people table, that contain json array of that person's jobs id, example : [1,2,4]
Method 2: Pivot
I would create pivot table job_person with job_id and person_id column, well, you know Laravel Eloquent style many to many pivot table
I have done some searching, and i found articels favouring each method, some say JSON better because it musch simpler, others would say Pivot is better due to that is how relationship database should work, etc etc.
But i want to know, which one should i use in what scenario? Like if it is just simple case like above scenario, JSON would be better?
What if there are other variables included like additional pivot columns
(Maybe each pivot also contain status column that can be set to active or past_job)
Or what if in the future we want to be able to get all peoples whom have a specific jobs, in which case Pivot would be preferable i think.
What if instead of jobs, the other table would be books and a person can have an extensive of books making we might have tens, or even hundreed pivot records just for one person? And there will be another hundreed persons?
What if instead of books, the other table were stocks in which case, a person might subscribed / unsubscribed multiple stock multiple times?
And maybe to the basic principle, what is each one's advantages/disadvantages?
Thank you very much
I would rather not choose JSON, as there's no benefit from choosing it, you will sacrifice many of the database features and make querying the data difficult and slow.
What if there are other variables included like additional pivot
columns (Maybe each pivot also contain status column that can be set
to active or past_job)
Job and Person are not dependent on each others, so you need to create an associative table between them something like "PersonJob" and add necessary information to it, this is easy to traverse in Laravel.
Or what if in the future we want to be able to get all peoples whom
have a specific jobs, in which case Pivot would be preferable i think.
You could easily query this using the associative table.
And maybe to the basic principle, what is each one's
advantages/disadvantages?
it just that relational databases are made for this kind of stuff and JSON offer no value just hardship.
In an app like StackOverflow (nothing really related but it's a good example), we have Questions. Each Question in our mongodb collection has an array of Answers, and an array of Votes (either upvoting or downvoting).
In each Answer, it is possible for a User to upvote or downvote it.
So the schema would look something like this:
Question
-> Answers []
-> Votes []
-> value (-1/1)
-> username
-> Votes []
-> value (-1/1)
-> username
-> question_text, etc.
Coming from a MySQL background this schema feels "icky" but I've been assured it's an industry practice.
Now I'm currently required to show each User what they have voted on, both in terms of Questions and Answers.
So if I have to find the Answer that a user has voted on, I would query thusly (in node):
question_collection.find(
{'question.answers.votes.username': username}, function(e,d) {
/* do stuff */}
);
That query goes 4 levels deep. Is this a normal way to do it or should I introduce some normalization in the schema?
One of the strengths of MongoDB is that you can put all relevant information about a Question inside one document, so you need only 1 database query and no joins to get all information to render the Question.
However, if you want to find everything a user has voted on, things get a bit more complicated. You can do what you do, certainly, although it won't win any performance awards.
Alternatively, you can duplicate the data in a smart way to access it in an easier way. For example, you could add two arrays to the User model:
QuestionsVoted: [{ id1: +1}, {id2: -1}, {id3: +1}],
AnswersVoted: [{ id4: +1}, {id5: -1}]
This means you need to keep this data in sync: when a user votes on a question or answer, you need to update both the question and the user. This is not that bad, because the data is written rarely and read often.
If you have other requirements that deal with votes themselves, for example statistics of votes over time, or by geographical region, you might want to create a Vote collection. And yes, you would have to keep the data in sync across 3 collections then.
It is technically possible to create foreign keys in MongoDB, but I would not recommend it in this case. You would lose some of the benefits of MongoDB, because it is not good at joins (it would require 2 separate queries).
You can read more about how to design relationships in MongoDB on their blog.
So I am trying to make a social network on Django. Like any other social network users get the option to like a post, and each of these likes are stored in a model that is different from the model used for posts that show up in the news feed. Now I have tried two choices to get the like status on the go.
1.Least database hits:
Make one sql query and get the like entry for every post id if they exist.Now I use a custom django template tag to see if the like entry for the current post exist in the Queryset by searching an array that contains like statuses of all posts.
This way I use the database to get all values and search for a particular value from the list using python.
2.Separate Database Query for each query:
Here i use the same custom template tag but rather that searching through a Queryset I use the mysql database for most of the heavy lifting.
I use model.objects.get() for each entry.
Which is a more efficient algorithm. Also I was planning on getting another database server, can this change the choice if network latency is only around 0.1 ms.
Is there anyway that I can get these like statuses on the go as boolean values along with all the posts in a single db query.
An example query for the first method can be like
Let post_list be the post QuerySet
models.likes.objects.filter(user=current_user,post__in = post_list)
This is not a direct answer to your question, but I hope it is useful nonetheless.
and each of these likes are stored in a model that is different from the model used for news feed
I think you have a design issue here. It is better if you create a model that describes a post, and then add a field users_that_liked_it as a many-to-many relationship to your user model. Then, you can do something like post.users_that_liked_it and get a query set of all users that liked your page.
In my eyes you should also avoid putting logic in templates as much as possible. They are simply not made for it. Logic belongs into the model class, or, if it is dependent on the page visited, in the view. (As a rule of thumb).
Lastly, if performance is your main worry, you probably shouldn't be using Django anyway. It is just not that fast. What Django gives you is the ability to write clean, concise code. This is much more important for a new project than performance. Ask yourself: How many (personal) projects fail because their performance is bad? And how many fail because the creator gets caught in messy code?
Here is my advice: Favor clarity over performance. Especially in a young project.
I can't find a way to define relationships. Here is my previous question, you can review it to find what I'm looking for: PHP/Laravel/Bootsrap fetch data
I've defined the relationship for skills like this:
public function skills()
{
return $this->hasMany('Skill', 'player_skills', 'skillid', 'player_id');
}
Still getting the Undefined property: Illuminate\Database\Eloquent\Collection::$players error pointing at $skills->players as $player.
First of all, with the hasMany function, you are setting up a one-to-many relationship, but it looks like you are sending it the name of a pivot table as a parameter, which would only be required for a many-to-many.
I'm going to assume you actually want a many to many relationship and your keys are correct (they are in the question you linked, but skillid is different here, so let's go with skill_id)
Also, the way you are looping through the data is wrong. $players->skills doesn't make any sense because $players doesn't have skills, but $player does.
Here is what I have so far... http://paste.laravel.com/Jp8
With the newest information you have given, I think there might be some confusion about how a many-to-many relationship works in Laravel. Please check this out when you get a chance, it should be pretty close to what you are looking for... http://paste.laravel.com/JqV
So, it may be best to just try it out and see through some trial and error, but I'm trying to figure out the best way to migrate a pretty simple structure from mysql to mongodb. Let's say that I have a main table in mysql called 'articles' and I have two other tables, one called 'categories' and the other 'category_linkage'. The categories all have an ID and a name. The articles all have an ID and other data. The linkage table relates articles to categories, so that you can have unlimited categories related to each article.
From a MongoDB approach, would it make sense to just store the article data and category ID's that belong to that article in the same collection, thus having just 2 data collections (one for the articles and one for the categories)? My thinking is that to add/remove categories from an article, you would just update($pull/$push) on that particular article document, no?
In my opinion, a good model would look like this:
{"article_name": "name",
"category": ["category1_name", "category2_name", ...],
"other_data": "other data value"
}
So, to embed the category names directly to the article document. Updating article categories is easy, but removing a category altogether requires modifying all articles belonging to the category. If removing categories is frequent, then keeping them separate might be a good idea performance-wise.
This approach makes it also easy to make queries on the category name (no need to map name to id with a separate query).
Thus, the "correct" way to model the data depends on the assumed use case, as is typically the case with mongodb and other nosql databases.
If you have access to a Mac computer, you could give the MongoHub GUI a try. It has an "Import from MySQL" feature.