How to determine the direction of an edge between vertexes in a Graph Database such as OrientDB - orientdb

How do we know if an edge is an out() going or in() coming in a graph database like OrientDB? I know that edges serve as links between vertexes (which is the same as a relationship between tables in RDMS), but how do we determine the direction. For example, I have some vertexes for Lecturer and courses, here, I want to have one (1) Lecturer to many Courses i.e. one-to-many relationship. So what is the direction of the edge between a lecturer and Courses, is it in() coming to the lecturer or out() going from a lecturer I mean how do I write the query using "select in() from lecturer" or select out() from lecturer? Thanks.

The direction of an edge is purely related to the domain and does not impact the traversal performance (ie. starting from a vertex, you can traverse incoming edges with the exact same performance as outgoing edges).
The important thing is to define the edge "name" in a meaningful way, so that the edge direction is clear.
I'll try to clarify with an example
Suppose you have two vertex classes: Person and Car.
Suppose you want to create a relationship within the two, to represent ownership (ie. a Person owns a Car).
Consider these two ways to represent the relationship:
Person -Owns-> Car
and
Person <-BelongsTo- Car
As you can see, both are clear and represent the domain very well.
Of course you have infinite alternatives to choose the edge name (btw, verbs are typically a very good choice), so you could choose something like "Ownership". This would be a definitely bad choice as it would not make the direction clear, eg.
is it
Person -Ownership-> Car
or is it
Person <-Ownership- Car
Imagine having to do a query on this schema after a few months you don't use it, with tens of relationships that are not semantically clear. You see the problem...
In the end, it's just a matter of how clear the model is. It's a human problem, not a technical problem.
I hope it helps

Undirected vs Directed edge
Undirected:
A -(Edge) - B
A can traverse to B, and B can traverse to A
Pros: Simple when working with undirected (symmetric) or bidirectional relationships.
Example: "A friend_of B" ⇔ "B friend_of A"
Cons: Does not carry directional info.
Directed Edge
A -(Edge) -> B
A can traverse to B, but B cannot traverse to A
Pros: Saves memory and correctly describes a direction-restricted relationship
Example: "A parent_of B" ⇏ "B parent_of A"
Cons: Can not traverse back from target to source.
Regarding Your Question - If it was me, I would choose undirected for your use case because most likely I would want to go both directions.

Related

DDD - Large aggregate and enforce invariant across aggregates

I'm kind of stuck at modeling this problem in the right way applying Domain Driven Design way. I want to model travelling group in a traveling agency.
We have concepts like passenger, group, and group member in one bounded context. This passenger is a large AR that holds all sorts of information, like name, job, address, bank account, religion, ANYTHING. But not all of them are necessary for all kinds of travels and their invariants differ based on the type of the trip. For example in travel type A, we don't need passengers' phone numbers. In travel type B we do. So when a person goes to create a group to go on travel type B, I will have an invariant on passenger AR to have a valid data for phone.
So basically there are two challenges here: How can I break this huge AR and how should I handle enforcing these conditional invariants? Is it OK if I enforce invariants on passenger AR inside handlers - application service- while creating group AR?
(Besides, the passenger AR and the group AR are in the same bounded context but they have the potential to be separated in the future).
I would say the constraint here should be not on passenger, but on the group.
At the end you may create passengers for different type of travels with or without phone numbers.
The actual constraint should be enforced like a passenger without a phone should not be added to that particular group as a group member.
Regarding the implementation side:
public void addPassengerToGroup(PassengerInformation passenger) {
//original code omitted
this.assertArgumentTrue(passenger.isPhoneInformationProvided(), "Passenger doesn't have contact information.");
this.groupMembers().add(passenger);
}
Somethink like this may solve your problem problem for constraint checks.
There is also some addition explanation for a similar situation:
https://softwareengineering.stackexchange.com/questions/319602/how-to-treat-validation-of-references-between-aggregates
This passenger is a large AR that holds all sorts of information, like name, job, address, bank account, religion, ANYTHING.
Well, to be honest, that sounds wrong as an aggregate. Consider why would you have this aggregate in the first place? What sort of business logic does this aggregate that involves the religion and bank account? or name? or address?
So, in short, this doesn't look like a Passenger aggregate. It looks more like a Customer record on a CRM without following DDD.
The first thing I would suggest is to consider your bounded contexts. I don't know your domain nor the specifics of your application, but most likely, you need bank account information for Finance reasons. So you'll have a Finance Bounded Context with Customers, their bank accounts, the invoices that you sent to them, and so on. You might also have a Bounded Context like Traveling or similar. Here, you might have a Passenger. A passenger could have a CustomerId and a TripId, plus other information, like ContactInformation and so on. You can also have Groups, with a list of Members and each Member could have a PassengerId and other information needed for the group management.
Obviously this is just an example from the limited information I have, but it seems to me, as I said, that a Customer becomes a Passenger when she signs up for a Trip. If the same Customer signs up for another trip, you'll create a new Passenger. There is no reason to reuse the same Passenger aggregate for multiple trips, because, as you said, even if it's the same person going to multiple Trips, the requirements for each are different, so trying to model a single Passenger that will fit all present and future types of Trips is creating an artificial coupling in my opinion.
Also, as I said previously, consider what information do you need on each aggregate. Even if across the whole application you know a lot of things from a single "person", it doesn't mean that you have to store them in a single place. That is the main point of DDD, in my opinion, finding where each piece of information belongs to and put it together with the business logic that needs it.

Whats is a RESTful way to get resources from all children?

Suppose I have the following api where vin is a Vehicle Identification Number and belongs to a single car.
GET /fleets/123/cars/55/vin
GET /fleets/123/cars/55/history
And I want to get all the vins for all the cars for a fleet. Which would be preferred among these:
GET /fleets/123/cars/all/vin
GET /fleets/123/cars/*/vin
GET /fleets/123/vins
GET /fleets/123/cars/vins
The first two preserve the hierarchy and make the controller more intuitive. The last three feels like it breaks consistency.
Are any of these preferred or is there a better way?
This is mostly an opinion-based question. There's no one true way here, so you'll get my opinion.
I'm not sure what a vin is, but if it's a type of resource, and there's a collection of vins as a child of a fleet resource, I would expect it to live here:
GET /fleets/123/vins
This communicates to me a vin is not a subordinate of a car. It's its own thing and I'm getting all vins for a specific fleet.
The fact that a vin also exists as a subordinate of car (to me) is kind of irrelevant to this. It makes perfectly sense to me that for those, that they live here:
GET /fleets/123/cars/55/vin
Similarly, if I would model the last 2 apis as 2 functions, I would call them:
findVinsForFleet(fleetId: number);
findVinForCar(fleetId: number, carId: number);

Core data max amount of entity

I am working on an app where I use core data.
I already have tried to do it with one entity but that didn't work.
But I now have like twenty entities and my question is: is there a limit to the number of entities or a number recommended?
Is there a better way to store that amount of data?
UPDATE:
What I am storing are grads from school but not the A,b,c,d,e,f but a number from 1 to 10. And each grad has is own weighing(amount of times a number count) like some grad count 2 time because the are more imported.
So i first thought to have an array with a string for the name of the subject and then to array one store's the grad the other the corresponding weighing.
Like this:
var subjects: [String,[Int],[Int]]
but this isn't possible and I don't even know how I should put this in core data and get it back properly.
Because I couldn't figure it out, I thought of just making a entity for each subject but there are a lot of them so there for this question.
There's no limit to the number of entities, but it's possible to go overboard and create more than you actually need. The recommended number is "as many as you need and no more", which obviously will vary a great deal depending on the nature of the data and how the app uses it. Whether there's a better way than your current approach is totally dependent on the fine details of exactly what you're doing, and so is impossible to answer without a far more detailed question.
You could setup a Subject entity that has one-to-many relationships to ordered sets of Grade and Weight, like so:
However, each grade apparently has a corresponding weight, so it would be more accurate to store each grade's weight in the Grade entity:
This still may not represent your real-world model.
If your subject is something general, like math or english, you could have more than one subject per grade, (e.g., algebra, geometry, trigonometry), or more than one level per subject (e.g., algebra 1, algebra 2) which may or may not have a different grade.
If your subject is very specific, your data may end up spread across unique one-to-one relationships, instead of one-to-many relationships.
You would also need to consider whether you can use ordered or unordered relationships, or whether an attribute exists that you can use to sort an entity.
You should consider these different facets of what you're trying to model (as well as the specific fetches you'd want to perform), before you try to design or implement the model, to allow you to efficiently represent this particular object graph.

Overpass relation railway segments

I want to query the Overpass Api to find out the distance of special relations (railways). The request is fine, and returns me all relation, way and node objects I'm interested in. Example for Hamburg:
[out:json];(rel(53.55224324163863, 10.006766589408304, 53.55314275836137, 10.008081410591696)["route"="train"];>;);out body;
In Overpass, each relation object has members defining this relation. For way objects you can resolve the lat/lon of its node attributes and calculate the distance for that way. If you sum up all the way distances it seems to be reasonable.
However, there are members from that relation of the type node (most of the time, they have a role of "stop") which seem to represent the right order of stops from that relation. But instead being in between the members, they are roughly at the end.
If I try to look the stops up inside the ways, they are not all present. How am I supposed to calculate the distance between two particular stops?
There seems to be a misconception about relations. Relation members don't necessarily have to be sorted. Consequently you might have to sort the members yourself, if necessary at all.
You can take a look at JOSM which has a neat sorting algorithm for various types of relations. But I don't think it is able to place members with the role stop at the correct position. This isn't always possible because a way doesn't necessarily have to be split at each node with the stop role. This also means a single way can contain more than one node with a stop role, making it impossible to sort the relation members correctly. Unless you do some pre-processing for splitting each way accordingly.
For calculating the distance between each stop it seems unnecessary to sort the elements. Just follow the way by iterating over all each nodes and check for each node if it has a stop role in the corresponding relation. When reaching the end of the way continue with the one which shares the same node at its start or end and which is also member of the relation.

"Frenemies", or How to Make Teenagers Happy at a Birthday Party

I have a combinatorial optimization problem that I am struggling with. The technical details of the problem are cumbersome, so I have translated things in terms of a fictitious sweet-16 birthday party. Obviously, teenagers are NP difficult, but that's separate from the actual problem I'm trying to solve.
Let's say I have a son who is about to turn 16. He invites all of his friends for his birthday party, but not all of his friends like each other. In fact, every friend of my son's has at least one person they don't like, and some have more. These "frenemies" refuse to sit at the same table if one or more sworn "frenemy" is sitting at the same table. My son has provided me a list of all his invited friends, and also who doesn't like who. This information is symmetrical (If friend A doesn't like friend B, friend B doesn't like friend A), but it is NOT transitive (If friend A doesn't like friend B, but likes friend C, friend C is still free to like or dislike friend B). My question is: How do I determine the minimum number of tables that satisfies the condition that no two "frenemies" are seated at the same table?
This is a combinatorial optimization problem, not a machine learning problem.
Actually, it is a coloring problem: Create a graph G, where each vertex corresponds to a person. An edge (u, v) exists iff the two persons u and v do not like each other. You are now asking for the smallest k such that G is k-colorable. A coloring c(v) tells you which table person v is seated at.
Now you just have to pick an algorithm.
This sounds more like a constrained optimisation problem than a machine learning problem to me. I would model it as follows.
One variable per friend, the value would be the table,
additional constraints (as per list) of the form friendX !- friendY to say that these two can't sit at the same table.
That's the basic model that you can solve using a constraint solver of your choice (I recomment Minion). You can either minimise the highest table number (which would require some additional constraints), or simply try to find a solution with a given number of tables (i.e. values in the domains of the variables) until you get down to one where no solution exists.
Depending on the size of the problem (i.e. number of friends and tables) this may or may not work. Something you may have to consider is the symmetry in the problem (i.e. the people on table A can move to table B and vice versa and it's still a solution) which could be broken with additional constraints.