Rails: How to model objects with a mix of both fixed and dynamic data - ruby-on-rails

I am building a site with a database of users. I am using arbor.js to build a graph for each user. The graph is a tree-like structure with edges and nodes that looks something like this (I had an image ready to go but apparently don't have enough reputation yet):
vehicle
/ \
/ \
car truck
/
/
sedan
and is represented by the following JSON:
{
"nodes":{
"vehicle":{
"color":"black",
"label":"vehicle"
},
"car":{
"color":"orange",
"label":"car"
},
"truck":{
"color":"red",
"label":"truck"
},
"sedan":{
"color":"red",
"label":"sedan"
}
},
"edges":{
"vehicle":{
"car":{
"weight":5,
"directed":true,
"color":"orange"
},
"truck":{
"weight":5,
"directed":true,
"color":"red"
}
},
"car":{
"sedan":{
"weight":2,
"directed":true,
"color":"orange"
}
}
}
}
Each graph will always have a nodes and edges object with dynamic nodes and edges. Their respective attributes (color, label, weight etc.) will be fixed.
I am trying to figure out how best to model this data for each user. I am using Rails with MongoDB (Mongoid), because I understand that MongoDB can save objects as documents in the database. I'm pretty sure each user will have a graph model which I can define, but beyond that I'm not sure how to handle the nodes and edges.
I'm guessing the solution will involve has_many, embeds_many, or possibly serialize, but I'm unclear on how to use these with a mix of fixed and dynamic data.
Also, it would be nice to retrieve the data exactly the way it looks above so I can easily create the graph when loading it from disk.
Any help would be appreciated!

In case all you need is to perform graph operations only per user. You can follow this model.
{
"nodes": [{"type": "vehicle", "color":"black", "label": "vehicle"},
{"type": "car", "color":"orange", "label": "car"},
{"type":"truck", "color":"red", "label":"truck"},
{"type": "sedan", "color":"red", "label":"sedan"}
],
"edges": {
"vehicle": [
{"type": "car", "weight": 5, "color": "orange"},
{"type": "truck", "weight": 5, "color": "red"}
],
"car": [
{"type": "sedan", "weight": 2, "color": "orange"}
],
"sedan": [],
"truck":: []
}
It is like you are storing a multimap for edges. Also it is self suggestive whether its a bi-directional or not. For individual user's graph to be processed independently, it is a pretty natural model you can go with.
Tell me if it meets your requirement. Also, until you specify what kind of queries you want to perform over your collection, its not possible to suggest a model.
Also if you are starting your project you can explore some graph databases as well like neo4j

Related

How to use a multi-layer map with countries and lakes with Highmaps?

Is there any way to use a multi-layer map in Highcharts? In my case, I need three layers: One for the countries, one for the borders (which show the disputed ones differently than the normal ones) and one for the lakes, like this:
In the moment, I don't see how this could be achieved. Or can I export the three layers from shapefile to JSON and then stick the three together? But would a »join« in order to color the countries still work?
Thanks for any hints.
According to the comments - something, like is required on the image, can be done by base on this official demo: https://jsfiddle.net/gh/get/library/pure/highcharts/highcharts/tree/master/samples/maps/demo/mapline-mappoint
After some attempts, #luftikus143 face into the issue that geometry can't be set as null in his custom JSON file and my solution is to assign it as an object with the empty coordinates array. Demo: jsfiddle.net/BlackLabel/06xvrs8m/1
{
"type": "Feature",
"geometry": {
type: 'polygon',
"coordinates": [
[
]
]
},
"properties": {
"OBJECTID": 1,
"NAME": "Great Bear Lake",
"Shape_Leng": 35.7525061159,
"Shape_Area": 6.12829979344
}
},

Relationship shown in Neo4j although it shouldn't [duplicate]

This question already has answers here:
How to hide unwanted relationships between nodes in Neo4j
(2 answers)
Closed 5 years ago.
I have created a small database with three nodes, Abraham, Isaac and Jacob. Abraham is Isaac's FATHER, and Isaac is Jacob's FATHER.
Now I perform the following query:
MATCH (a:Person), (i:Person)
WHERE a.name='Abraham' and i.name='Isaac'
RETURN a, i
Running the query from the Neo4J web interface shows the two nodes with the FATHER relationship between them:
This is strange, as I have not requested any relationships. The JSON response doesn't contain the relationships, either:
[{
"keys": [
"a",
"i"
],
"length": 2,
"_fields": [
{
"identity": {
"low": 0,
"high": 0
},
"labels": [
"Person"
],
"properties": {
"name": "Abraham"
}
},
{
"identity": {
"low": 1,
"high": 0
},
"labels": [
"Person"
],
"properties": {
"name": "Isaac"
}
}
],
"_fieldLookup": {
"a": 0,
"i": 1
}
}]
Why is Neo4J showing this relationship? And how can I make it stop? I'm trying to create a query that returns various relationships between a set of nodes, and I really don't want Neo4J interfering and adding its own relationships.
It just the way the Neo4j browser visualizes, nothing more. Since you've got both nodes, Neo4j has everything it needs (the pointers) to know that there is a relationship (and shows it). If you process the result programmatically (in Java or such ... as you're bound to do since I assume the Neo4j browser will not be the "production" result) you will be able to process the results as you wish. If you're only interested in the names and not the actual nodes, just do
MATCH (a:Person), (i:Person)
WHERE a.name='Abraham' and i.name='Isaac'
RETURN a.name, i.name
Hope this helps.
Regards,
Tom

Report Filtering With Adobe Analytics API

I am queuing and getting a report through the API and javascript, but now I want to start filtering the report. I want the results that come back to apply only to the user (other filters are needed too) who is requesting the report. What is the best way to put a filter on the initial report queue?
The way I am doing it now is adding a selected element to the report description:
...
"elements": [
{ "id": "page" },{ "id": "evar23" , "selected": ["295424","306313"]}
...
But this only seems to apply to the breakdown section of the results, not the top level count that is returned. I would expect the top level count in the below example be 66, not 68:
...
"counts":[
"68"
],
"breakdown":[
{
"name":"306313",
"url":"",
"counts":[
"43"
]
},
{
"name":"295424",
"url":"",
"counts":[
"23"
]
}
]
}
,...
I know I can just crawl through the breakdown array and total up what I need, but the more filters I apply the messier it becomes. All of a sudden I am three levels deep in a nested array, making sure that all 3 breakdown names match my conditions. There must be a better way to do this, any ideas? Many thanks.
Although there are some possible limitations to them that I am still working through, it seems that segments is what I need, not elements.
"segments": [
{
"element": "evar23","selected": ["295424","306313"]
}]
https://marketing.adobe.com/developer/forum/reporting/report-filtering-with-api

The graph section of Cypher response, remains blank

I noticed for some queries the response populates the "graph" section as follows
}
],
"graph": {
"nodes": [
{
"id": "68",
"labels": [
"ROOM"
],
"properties": {
"id": 15,
"name": "Sun and Snow",
but for other queries, this "graph" section is not returning with nodes/relationships and associated labels/properties even though the "data" section returns valid output
Does it convey anything about the quality of the cypher query ?
It depends on what you return from your query. If you return nodes and relationships, you'll get a graph. If you return scalars such as n.name or r.weight, you don't get a graph.
Are you talking about the HTTP requests from the web UI or requests that you are making yourself?
The graph key is controlled via the resultDataContents option when making a request. You can see the documentation for that here:
http://neo4j.com/docs/stable/rest-api-transactional.html#rest-api-return-results-in-graph-format
You can request multiple formats for the result ("row" and "REST" are other examples)

how to get the distance or radian between two point on the earth with lng and lat?

how to get the distance or radian between two point on the earth with lng and lat?
You probably don't want mapReduce in this case but actually the aggregation framework. Apart from the general first stage query you can run via $geoNear which is more efficient in your purpose.
db.places.aggregate([
{ "$geoNear": {
"near": {
"type": "Point",
"coordinates": [ -88 , 30 ]
},
"distanceField": "dist"
}},
{ "$match": {
"loc": {
"$centerSphere": [ [ -88 , 30 ] , 0.1 ]
}
}}
])
Or frankly, because the initial $geoNear stage will "project" an additional field into the document containing the "distance" from the queried "point of origin", then you can just "filter" on that element in a subsequent stage:
db.places.aggregate([
{ "$geoNear": {
"near": {
"type": "Point",
"coordinates": [ -88 , 30 ]
},
"distanceField": "dist"
}},
{ "$match": {
"dist": { "$lte": 0.1 }
}}
])
Since this is one option that can "produce/project" a value representing the distance in the result then that satisfies your first criteria. The "chaining" nature of the "aggregation framework" allows "additional filtering" or any other operation you need to perform after the filtering of the initial query.
So $geoWithin works just as well in the aggregation framework under a $match stage as it would in any standard query since it is not "dependant" on an "index" of geospatial origin to be present. It performs better in an initial query with one, but it does not need it.
Since your requirement is the "distance" from the point of origin, then the most logical thing to do is to perform an operation that will return such information. Such as this does.
Would love to include all of the relevant links in this response, but as a new responder then two links is all I am allowed for now.
One more relevant note:
The measurement of "distance" or "radius" in any operation is dependant on how your data is stored. If it is in a "legacy" or "key/pair or plain array" format then the value will be expressed in "radians", otherwise where the data is expressed in GeoJSON format on the "location" then the "distance data" is expressed in "meters" instead.
That is an important consideration given the libraries implemented by the MongoDB service and how this interacts with the data as you have it stored. There is of course documentation on this in the official resources should you care to look at that properly. And again, I cannot add those links at this time, unless this response sees some much needed love.
https://github.com/mongodb/mongo/blob/master/src/third_party/s2/s2latlng.cc#L37
GetDistance() return a S1Angle, S1Angle::radians() will return the radians.
This belong to s2-geometry-library(google code will close,i export it to my github. Java).

Resources