cosmos gremline cross container mapping - azure-cosmosdb

Cosmos DB Gremlins two graph ( container ) - graph1 & graph 2 .
graph1- - person(node )
graph2- - city(node )
can we make edge between person and city where they are located different container ?

can we make edge between person and city where they are located different container ?
No, AFAIK it is not possible. You can only connect two nodes in the same container.

Related

gremlin traversal on AWS neptune

I have a graph structure like this-
Node1(Console) <----Uses--- Node2(Name, Age) -----plays----> Node3(Game)
So, i have three nodes -
Node1 is console like a PS3/ Nintendo.
Node2 is a person with properties name and Age.
Node3 is game node which holds game name like 'warcraft'.
Now I want to have a gremlin query which tells me that.
How many users (Node2) who has the console like PS3, plays a game like 'warcraft'
I think i need to start the traverse from Node2 , filter it based on Node1 property i.e console as as 'PS3' and plays game like 'warcraft'
I am new to gremlin and using some thing like this -
g.V().hasLabel('user').outE('uses').inV().has('console', 'ps3').count()
the above query only answers half of my required result. How do i filter Node2 based on plays relationship as well.
Any help is appreciated.
There are multiple ways to write the query.
Option 1: Start from console
g.V().has('console', 'ps3').in('uses').where(out('plays').has('game', 'warcraft')).valueMap('name')
Let me explain the structure here:
g.V().has('console', 'ps3') --> Select all vertices which have a property with key as console and value as ps3
in('uses') --> From the set of previous vertices, jump to incoming vertices via an edge that has the label uses. At this stage, we would have player vertices in our solution.
where(out('plays').has('game', 'warcraft')) --> Apply a filter on existing solutions. Since we are using where we would not jump/traverse to the next step of vertices.
valueMap('name') --> Project one or more properties if existing solutions which are player vertices.
Option 2: Another way to write above query
g.V().has('console', 'ps3').in('uses').as('myusers').out('plays').has('game', 'warcraft').select('myusers').by('name')
as('myusers') --> Provides a reference/alias to the vertices at this stage. Note that it does not store all the results at this stage instead it just provides a reference to the type of vertices at this point in the query.
out('plays').has('game', 'warcraft') --> Unlike previous time when we did not jump since we were using where, this time we jump onto the game vertices.
select('myusers').by('name') --> since we want to project the users but the current solutions are game vertices, we need to select the user vertices which we do using the reference we stored earlier.
Option 3: Start from user
g.V().hasLabel('user').where(out('plays').has('game','warcraft')).where(out('uses').has('console','ps3')).valueMap('name')
There are more ways to write this query such as using path() but I won't go into details here.
Since you are beginning to learn Gremlin, I would recommend that you start with https://kelvinlawrence.net/book/Gremlin-Graph-Guide.html

From a given node get reachable node following unidirectional relationship and display that sub-graph as a tree

here is my problem:
I've got a graph where I have :Item with one relationship :CRAFTED_WITH to one :RECIPE and those :RECIPEhave one or more relationship :COMPOSED_OF{quantity} to ingredients that are :Item.
As you can imagine you can have several level of relationship to get from a high tier :Item to the most basic of components.
I want to be able to find all nodes that are reachable from a specific node while following only one direction. That part was easy I used the apoc procedure apoc.path.subgraphAll.
But now my next step is to have the result display as a tree and not a graph. In a graph I will ended up with multiple :Item on the receiving end of :COMPOSED_OF relationship. I want :Item to be "duplicated" so they are linked by a single :COMPOSED_OF relationship.
Is it even feasible only in cypher ? Or will I have to use another language to handle a graph to turn it into that "tree" structure ?
There is an apoc function to do that. The cypher below illustrates what is does.
MATCH treePath=(root:Thing)-[:CHILD*0..]->(leaf:Thing)
WHERE NOT (leaf)-[:CHILD]->()
AND NOT ()-[:CHILD]->(root)
WITH COLLECT(treePath) AS treePaths
CALL apoc.convert.toTree(treePaths) yield value AS tree
RETURN tree

DynamoDB Schema - Modeling Locations inside a building

New to DynamoDB over here. I need to figure out a DynamoDB schema for different locations inside a building. Additionally, I need to be able to identify computers assigned to each of the locations. The locations are nested inside other locations. For instance,
Building 1
Wing A
Floor 1
Section A
Office 1
Computer A
Computer B
Office 2
Computer A
Section B
Office 1
... and so on.
ACCESS PATTERNS:
Show all of the locations (wings, Floors, sections, etc) in a building
Show a specific location
Show all of the computers assigned to a specific location
Show the location of a specific computer
What I was thinking:
I initially wanted to create something like this:
PartitionKey SortKey Attributes
Building#1 Building#1 (For metadata)
Building#1 Section#1 [...]
Building#1 Section#1|Section#2 [...]
Building#1 Section#1|Section#2|Section#3 [...]
I know this is the wrong way to think about it, but I can't figure out any other way.
What is the best way to model the location of sections, offices, etc of a building?
If those are really the only access patterns you can probably do something with a simple GSI. I wouldn't using Building as the PartitionKey because this will give you a lot of hot spots in the data. Something like this would probably work:
PartitionKey SortKey GSI_PartitionKey GSI_SortKey Attributes
Building#1 'Location' [...]
Wing#1 'Location' 'Location' Building#1 . [...]
Floor#1 'Location' 'Location' Building#1|Wing#A [...]
.
.
.
Computer#1 'Computer' 'Computer' B#1|W#A|F#1|S#A|O#1 [...]
Computer#2 'Computer' 'Computer' B#1|W#A|F#1|S#B|O#1 [...]
.
.
.
The SortKey values here are more optional, but they tend to allow for changes later without as much work now.
To get all the locations in a building you query the GSI where the GSI_PartitionKey is 'Location' and the GSI_SortKey begins with your building ID. You can add sub locations to the string so you can get all the locations in Wing A with a begins with of Building#1|Wing#A|
Get a specific location using the PartitionKey (and optionally the SortKey = 'Location').
To get all the computers in a locations GSI where the GSI_PartitionKey is 'Computer' and the GSI_SortKey begins with your location ID.
Get a specific computer using the PartitionKey (and optionally the SortKey = 'Computer') the attributes should include it's location.
I think you're on the right track...
Having the hierarchical data coded as a delimited sort key seems to follow the recommendations I've seen (though your two sets of example data don't match) Section#1|Section#2|Section#3 vs Wing A|Floor 1|Section A
I'd probably consider having the table with just a hash of "serial number" or "asset ID"
Then have a GSI with the key's you describe.

Janusgraph - How to hide the edge relation between two vertices and establish / retrieve again based on a condition?

I'm new to the Janusgraph Database. I have a requirement where I need to hide the relation (edge) between two vertices without dropping them and later I should able retrieve / establish the same relation again between those vertices based on condition.
I only know how to drop the edges but I don't know how to retrieve/restore the relation again. Could you please help me out here.
Thanks a lot for your time.
If you want to 'restore' the connections I think you shouldn't drop them at all.
Just keep a property on the edge that indicates the edge state (active/inactive) or maybe keep a start and end date on the edge.
This way when you traverse your graph you need to makes sure to use only the active edges, but the old ones can still easily found if you want to restore them.
for example:
g.addV('person').property('id', 'bob').property('name', 'Bob')
g.addV('person').property('id', 'alice').property('name', 'Alice')
g.addV('person').property('id', 'eve').property('name', 'Eve')
g.V('bob').addE('friend').to(g.V('alice'))
g.V('bob').addE('friend').to(g.V('eve'))
So Bob friends with Alice and Eve:
g.V('bob').out('friend').values("name")
==>Alice
==>Eve
Let say Bob and Alice had a fallout, and they are no longer friends:
g.V('bob').outE('friend').where(inV().hasId('alice')).property('status', 'inactive')
now you can query only Bob active friends, without dropping the old edges:
g.V('bob').outE('friend').not(has('status', 'inactive')).inV().values("name")
==> Eve

neo4j Cypher Query

i have a following graph in neo4j graph database and by using the cypher query language, i want to retrieve the whole data with is connected to root node and their child node.
For example :
kindly find the below graph image.
[As per the image, node 1 has two child and their child also have too many child with the same relationship. now what i want, using Cypher, i hit the node 1 and it should response with the whole data of child node and there child node and so on, relationship between nodes are "Parent_of" relationship.]
can anyone help me on this.
start n=node(1) // use the id, or find it using an index
match n-[:parent_of*0..]->m
return m
will get you all the graph nodes in m. You could also take m.some_property instead of m if you don't want the node itself, but some property that is stored in your nodes.
Careful though, as the path has no limit, this query could become pretty huge in a large graph.
You can see an example of *0.. here: http://gist.neo4j.org/?6608600

Resources