class User(nm.StructuredNode): uid = nm.StringProperty(index=True, default=uuid4) create_datetime = nm.DateTimeProperty(default_now=True) email = nm.StringProperty(unique_index=True, required=True) password = nm.StringProperty(required=True) name = nm.StringProperty(required=True) liked_posts = nm.RelationshipTo('Post', 'LIKED', model=Like) followings = nm.RelationshipTo('User', 'FOLLOW')
class AuthorNode(DjangoNode): author_id = neomodel.IntegerProperty( unique_index=True) # This correspond one-to-one to Author model in SQL coauthors = neomodel.Relationship('AuthorNode', 'COAUTHOR', model=Coauthorship) papers = neomodel.RelationshipTo('DocumentNode', 'OWNS')
class BasePerson(neomodel.StructuredNode): """ Base class for defining some basic sort of an actor. """ name = neomodel.StringProperty(required = True, unique_index = True) friends_with = neomodel.RelationshipTo("BasePerson", "FRIENDS_WITH", model = PersonalRelationship)
class Location(neomodel.StructuredNode): location_id = neomodel.IntegerProperty(unique_index=True) name = neomodel.StringProperty(required=True) parent = neomodel.RelationshipTo("Location", "IS_IN", neomodel.ZeroOrOne, model=LocationRelationship) def __str__(self): return self.name
class News(neomodel.StructuredNode): headline = neomodel.StringProperty(unique_index=True, required=True) url = neomodel.StringProperty(required=False) publisher = neomodel.StringProperty(required=False) created_at = neomodel.DateTimeProperty(required=False) keywords = neomodel.ArrayProperty(neomodel.StringProperty(), required=False) score = neomodel.FloatProperty(required=False) cites = neomodel.RelationshipTo('Company', 'CITES')
class order(nm.StructuredNode): price = nm.FloatProperty() shares = nm.FloatProperty() date = nm.DateTimeProperty(default_now=True) if shares.__gt__ == 0: side = 'buy' else: side = 'sell' company = nm.RelationshipTo('Company', side.upper())
class Recipe(nm.StructuredNode): r_id = nm.UniqueIdProperty() title = nm.StringProperty() description = nm.StringProperty() requires = nm.RelationshipTo('Ingredient', 'REQUIRES', model=Requires) def to_dict(self): return { 'r_id': self.r_id, 'title': self.title, 'description': self.description }
class User(neomodel.StructuredNode): id_str = neomodel.StringProperty(unique_index=True, required=True) name = neomodel.StringProperty(required=False) screen_name = neomodel.StringProperty(required=False) followers_count = neomodel.IntegerProperty(required=False) friends_count = neomodel.IntegerProperty(required=False) modified = neomodel.DateTimeProperty(required=False) created_at = neomodel.DateTimeProperty(required=False) description = neomodel.StringProperty(required=False) location = neomodel.StringProperty(required=False) coordinates = neomodel.ArrayProperty(required=False, default=[]) time_zone = neomodel.StringProperty(required=False) url = neomodel.StringProperty(required=False) lang = neomodel.StringProperty(required=False) follows = neomodel.RelationshipTo('User', 'FOLLOWS') posts = neomodel.RelationshipTo('Tweet', 'POSTS') def save(self): self.modified = datetime.datetime.now() super(User, self).save()
class Tweet(neomodel.StructuredNode): id_str = neomodel.StringProperty(unique_index=True, required=True) created_at = neomodel.DateTimeProperty(required=False) modified = neomodel.DateTimeProperty(required=False) retweeted = neomodel.BooleanProperty(required=False) retweet_id_str = neomodel.StringProperty(required=False, default='') reply_id_str = neomodel.StringProperty(required=False, default='') quote_id_str = neomodel.StringProperty(required=False, default='') mention_ids_str = neomodel.ArrayProperty(required=False, default=[]) text = neomodel.StringProperty(required=False) coordinates = neomodel.ArrayProperty(required=False, default=[]) lang = neomodel.StringProperty(required=False) features = neomodel.JSONProperty(required=False, default={}) sentiment_polarity = neomodel.FloatProperty(required=False) sentiment_subjectivity = neomodel.FloatProperty(required=False) retweets = neomodel.RelationshipTo('Tweet', 'RETWEETS') mentions = neomodel.RelationshipTo('User', 'MENTIONS') replies = neomodel.RelationshipTo('Tweet', 'REPLIES') tags = neomodel.RelationshipTo('Hashtag', 'TAGS') contains = neomodel.RelationshipTo('Link', 'CONTAINS') quotes = neomodel.Relationship('Tweet', 'QUOTES') tweet_about = neomodel.RelationshipTo('Company', 'TWEETS') def save(self): self.modified = datetime.datetime.now() super(Tweet, self).save() return self
class Event(neomodel.StructuredNode): name = neomodel.StringProperty(unique_index=True, required=True) weighting = neomodel.FloatProperty(required=False) modified = neomodel.DateTimeProperty(required=False) related_to = neomodel.RelationshipTo('Company', 'ABOUT') tweet_from = neomodel.RelationshipFrom('Tweet', 'TWEET_FROM') cited_from = neomodel.RelationshipFrom('News', 'CITE_FROM') def save(self): self.modified = datetime.datetime.now() super(Event, self).save() return self
class Company(nm.StructuredNode): name = nm.StringProperty(unique_index=True, require=True) symbol = nm.StringProperty() market = nm.StringProperty() list_date = nm.IntegerProperty() updated = nm.DateTimeProperty(default_now=True) concept = nm.RelationshipTo('Concept', 'COMPONENT_OF', cardinality=nm.ZeroOrMore, model=ComponentRel) industry = nm.RelationshipTo('Industry', 'COMPONENT_OF', cardinality=nm.ZeroOrMore, model=ComponentRel) index = nm.RelationshipTo('Industry', 'COMPONENT_OF', cardinality=nm.ZeroOrMore, model=ComponentRel) customer = nm.RelationshipTo('Company', 'SUPPLIES_TO', cardinality=nm.ZeroOrMore) product = nm.RelationshipTo('Product', 'PRODUCES', model=ProductRel)
class Movie(neo.StructuredNode): uid = neo.IntegerProperty() title = neo.StringProperty() vote = neo.StringProperty() overview = neo.StringProperty() poster = neo.StringProperty() date = neo.StringProperty() language = neo.StringProperty() producer = neo.RelationshipTo('Producer', 'PRODUCE_BY', cardinality=ZeroOrOne) compositor = neo.RelationshipTo('Compositor', 'COMPOSED_BY', cardinality=ZeroOrOne) director = neo.RelationshipTo('Director', 'LEAD_BY', cardinality=ZeroOrOne) actors = neo.RelationshipTo('Actor', 'PLAYED_BY', cardinality=ZeroOrMore) genres = neo.RelationshipTo('Genre', 'OWN', cardinality=ZeroOrMore) keywords = neo.RelationshipTo('Keyword', 'IS', cardinality=ZeroOrMore) @property def serialize(self): return { 'id': self.uid, 'title': self.title, 'vote_average': self.vote, 'overview': self.overview, 'poster_path': self.poster, 'release_date': self.date, 'original_language': self.language } @classmethod def related_base(cls, name, selection): return neo.db.cypher_query( f"""MATCH (Base {{name:"{name}"}})--(m:Movie)--(b:Base) WHERE NOT m.uid IN {selection} RETURN m, collect(b) LIMIT 50""")[0] @classmethod def matrix(cls, selection_ids): return neo.db.cypher_query(f"""MATCH (p)-[r]-(m:Movie) WHERE m.uid in {selection_ids} WITH p, Count(r) AS CountRelation RETURN p, CountRelation ORDER BY CountRelation DESC LIMIT 30""")
class ExtendedSomePerson(SomePerson): friends_with = neomodel.RelationshipTo( "BaseOtherPerson", "FRIENDS_WITH", model=ExtendedPersonalRelationship)
class Deck(nm.StructuredNode): name = nm.StringProperty(unique_index=True) cards = nm.RelationshipTo('Card', 'CARD') attributes = nm.ArrayProperty() pk_field = 'name'
class Actor(neo.StructuredNode): git_id = neo.StringProperty(unique_index=True) login = neo.StringProperty(unique_index=True) visible_login = neo.StringProperty() contributed = neo.RelationshipTo('Repo', 'CONTRIBUTED', model=Contribution)
class BaseEntity(neomodel.StructuredNode): name = neomodel.StringProperty(unique_index=True) variants = neomodel.JSONProperty() best_variant = neomodel.StringProperty() count = neomodel.IntegerProperty(default=1) weight = neomodel.FloatProperty(default=0) create_at = neomodel.DateTimeFormatProperty(format=DATETIME_FORMAT, default_now=True) # GOD attributes: relation from head (self) to Tail (other) used_for = neomodel.RelationshipTo(neomodel.StructuredNode, 'used_for', model=UsedFor) part_of = neomodel.RelationshipTo(neomodel.StructuredNode, 'part_of', model=PartOf) feature_of = neomodel.RelationshipTo(neomodel.StructuredNode, 'feature_of', model=FeatureOf) compare = neomodel.RelationshipTo(neomodel.StructuredNode, 'compare', model=Compare) hyponym_of = neomodel.RelationshipTo(neomodel.StructuredNode, 'hyponym_of', model=HyponymOf) evaluate_for = neomodel.RelationshipTo(neomodel.StructuredNode, 'evaluate_for', model=EvaluateFor) refer_to = neomodel.RelationshipTo(neomodel.StructuredNode, 'refer_to', model=ReferTo) appear_in = neomodel.RelationshipTo(neomodel.StructuredNode, 'appear_in', model=AppearIn) author_of = neomodel.RelationshipTo(neomodel.StructuredNode, 'author_of', model=AuthorOf) affiliate_with = neomodel.RelationshipTo(neomodel.StructuredNode, 'affiliate_with', model=AffiliateWith) cite = neomodel.RelationshipTo(neomodel.StructuredNode, 'cite', model=Cite) related_to = neomodel.RelationshipTo(neomodel.StructuredNode, 'related_to', model=RelatedTo)
class Deck(nm.StructuredNode): name = nm.StringProperty(unique_index=True) cards = nm.RelationshipTo('Card', 'CARD') owner = nm.RelationshipFrom('User', 'USER', cardinality=nm.One) attributes = nm.ArrayProperty()
def get_or_create_class(identifier, entry, classdata, propdata, sources, fields={}, rel_fields={}): """ Get a class from the current namspace, or create and register one. Parameters ---------- identifier : str Unique name of the class. entry : dict Metadata for the class. Expects (but does not require) keys ``comment``, ``label``, ``code``, and ``safe_name``. classdata : dict All raw metadata for the classes in this schema, keyed on identifier. propdata : dict All raw metadata for the properties (relations) in this schema, keyed on identifier. sources : dict Hashtable containing (values) a list of property identifiers that belong to each class identifier (keys). fields : dict (optional) Specify extra fields to add to the class specification. Keys should be valid property names, and values should be callables that return :class:`neomodel.properties.Property` instances. rel_fields : dict (optional) Specify extra fields to add to linked relation class specifications. Keys should be valid property names, and values should be callables that return :class:`neomodel.properties.Property` instances. Returns ------- :class:`type` """ _globs = globals() if identifier in _globs: return _globs[identifier] if entry.get('subClassOf'): super_identifiers = entry.get('subClassOf') superClasses = tuple([get_or_create_class(ident, classdata[ident], classdata, propdata, sources, fields=fields, rel_fields=rel_fields) for ident in super_identifiers]) else: superClasses = (HeritableStructuredNode,) params = { '__doc__': entry.get('comment', ""), 'description': entry.get('comment', ""), 'display_label': entry.get('label'), 'code': entry.get('code'), 'safe_name': entry.get('safe_name') } for key, val in fields.items(): # TODO: ensure that ``key`` is a valid property name. if hasattr(val, '__call__') and key not in params: val = val() if not isinstance(val, neomodel.properties.Property): continue params[key] = val property_identifiers = sources.get(identifier, []) for ident in property_identifiers: prop = propdata.get(ident) target_identifier = prop.get('range') target_class = get_or_create_rel_class(ident, prop, fields=rel_fields) rel = neomodel.RelationshipTo(target_identifier, ident, model=target_class) params[prop.get('safe_name')] = rel _globs[identifier] = type(str(identifier), superClasses, params) return _globs[identifier]
class Fund(nm.StructuredNode): name = nm.StringProperty(unique_index=True, require=True) rating = nm.IntegerProperty() company = nm.RelationshipTo('Company', 'STAKES', model=StakeRel)
class ASTNode(neomodel.StructuredNode): # properties Id = neomodel.UniqueIdProperty() Type = neomodel.StringProperty() Kind = neomodel.StringProperty() Code = neomodel.StringProperty() Range = neomodel.StringProperty() Location = neomodel.StringProperty() Value = neomodel.StringProperty() Raw = neomodel.StringProperty() Async = neomodel.StringProperty() SemanticType = neomodel.StringProperty() # Abstract Syntax Tree (AST) relationships ASTConnectionsTo = neomodel.RelationshipTo('ASTNode', 'AST_parentOf', model=RelationshipSchema) ASTConnectionsFrom = neomodel.RelationshipFrom('ASTNode', 'AST_parentOf', model=RelationshipSchema) ASTConnections = neomodel.Relationship('ASTNode', 'AST_parentOf', model=RelationshipSchema) # Control Flow Graph (CFG) relationships CFGConnectionsTo = neomodel.RelationshipTo('ASTNode', 'CFG_parentOf', model=RelationshipSchema) CFGConnectionsFrom = neomodel.RelationshipFrom('ASTNode', 'CFG_parentOf', model=RelationshipSchema) CFGConnections = neomodel.Relationship('ASTNode', 'CFG_parentOf', model=RelationshipSchema) # Program Dependence Graph (PDG) relationships PDGConnectionsTo = neomodel.RelationshipTo('ASTNode', 'PDG_parentOf', model=RelationshipSchema) PDGConnectionsFrom = neomodel.RelationshipFrom('ASTNode', 'PDG_parentOf', model=RelationshipSchema) PDGConnections = neomodel.Relationship('ASTNode', 'PDG_parentOf', model=RelationshipSchema) # Inter-Procedural Call Graph (IPCG) relationships IPCGConnectionsTo = neomodel.RelationshipTo('ASTNode', 'CG_parentOf', model=RelationshipSchema) IPCGConnectionsFrom = neomodel.RelationshipFrom('ASTNode', 'CG_parentOf', model=RelationshipSchema) IPCGConnections = neomodel.Relationship('ASTNode', 'CG_parentOf', model=RelationshipSchema) # Event Registration of ERDDG relationships ERDDGRegistrationConnectionsTo = neomodel.RelationshipTo( 'ASTNode', 'ERDDG_Registration', model=RelationshipSchema) ERDDGRegistrationConnectionsFrom = neomodel.RelationshipFrom( 'ASTNode', 'ERDDG_Registration', model=RelationshipSchema) ERDDGRegistrationConnections = neomodel.Relationship( 'ASTNode', 'ERDDG_Registration', model=RelationshipSchema) # Event Dispatch of ERDDG relationships ERDDGDispatchConnectionsTo = neomodel.RelationshipTo( 'ASTNode', 'ERDDG_Dispatch', model=RelationshipSchema) ERDDGDispatchConnectionsFrom = neomodel.RelationshipFrom( 'ASTNode', 'ERDDG_Dispatch', model=RelationshipSchema) ERDDGRegistrationConnections = neomodel.Relationship( 'ASTNode', 'ERDDG_Registration', model=RelationshipSchema) # Event Dependency of ERDDG relationships ERDDGDependencyConnectionsTo = neomodel.RelationshipTo( 'ASTNode', 'ERDDG_Dependency', model=RelationshipSchema) ERDDGDependencyConnectionsFrom = neomodel.RelationshipFrom( 'ASTNode', 'ERDDG_Dependency', model=RelationshipSchema) ERDDGDependencyConnections = neomodel.Relationship( 'ASTNode', 'ERDDG_Dependency', model=RelationshipSchema) # ------------------------------------------------------------------------------------------------ # # General Methods # ------------------------------------------------------------------------------------------------ # def get_line(self): """ @return {list|None}: [(a, b)] where a, b are the start and end lines for the code of the AST node """ if self.location is not None: loc = eval(self.location) return [loc.start.line, loc.end.line] return None def is_cfg_node(self): # TODO pass def has_cfg_edge(self): # TODO pass def has_pdg_edge(self): # TODO pass # ------------------------------------------------------------------------------------------------ # # Edge Traversals # ------------------------------------------------------------------------------------------------ # def get_connections_by_ast(self, direction=neomodel.match.OUTGOING, **kwargs): """ @param {string} direction: neomodel.match.OUTGOING / neomodel.match.INCOMING / neomodel.match.EITHER @param **kwargs: positional keyword arguments specifying the constraints on the edges for traversals @return {list}: related AST nodes """ if direction == neomodel.match.OUTGOING: return self.ASTConnectionsTo.match(**kwargs).all() elif direction == neomodel.match.INCOMING: return self.ASTConnectionsFrom.match(**kwargs).all() else: return self.ASTConnections.match(**kwargs).all() def get_connections_by_cfg(self, direction=neomodel.match.OUTGOING, **kwargs): """ @param {string} direction: neomodel.match.OUTGOING / neomodel.match.INCOMING / neomodel.match.EITHER @param **kwargs: positional keyword arguments specifying the constraints on the edges for traversals @return {list} related CFG nodes """ if direction == neomodel.match.OUTGOING: return self.CFGConnectionsTo.match(**kwargs).all() elif direction == neomodel.match.INCOMING: return self.CFGConnectionsFrom.match(**kwargs).all() else: return self.CFGConnections.match(**kwargs).all() def get_connections_by_pdg(self, direction=neomodel.match.OUTGOING, **kwargs): """ @param {string} direction: neomodel.match.OUTGOING / neomodel.match.INCOMING / neomodel.match.EITHER @param **kwargs: positional keyword arguments specifying the constraints on the edges for traversals @return {list} related PDG nodes """ if direction == neomodel.match.OUTGOING: return self.PDGConnectionsTo.match(**kwargs).all() elif direction == neomodel.match.INCOMING: return self.PDGConnectionsFrom.match(**kwargs).all() else: return self.PDGConnections.match(**kwargs).all() def get_connections_by_ipcg(self, direction=neomodel.match.OUTGOING, **kwargs): """ @param {string} direction: neomodel.match.OUTGOING / neomodel.match.INCOMING / neomodel.match.EITHER @param **kwargs: positional keyword arguments specifying the constraints on the edges for traversals @return {list} related IPCG nodes """ if direction == neomodel.match.OUTGOING: return self.IPCGConnectionsTo.match(**kwargs).all() elif direction == neomodel.match.INCOMING: return self.IPCGConnectionsFrom.match(**kwargs).all() else: return self.IPCGConnections.match(**kwargs).all() def get_connections_by_erddg_dispatch(self, direction=neomodel.match.OUTGOING, **kwargs): """ @param {string} direction: neomodel.match.OUTGOING / neomodel.match.INCOMING / neomodel.match.EITHER @param **kwargs: positional keyword arguments specifying the constraints on the edges for traversals @return {list} related nodes via ERDDG Dispatch edges """ if direction == neomodel.match.OUTGOING: return self.ERDDGDispatchConnectionsTo.match(**kwargs).all() elif direction == neomodel.match.INCOMING: return self.ERDDGDispatchConnectionsFrom.match(**kwargs).all() else: return self.ERDDGDispatchConnections.match(**kwargs).all() def get_connections_by_erddg_registration(self, direction=neomodel.match. OUTGOING, **kwargs): """ @param {string} direction: neomodel.match.OUTGOING / neomodel.match.INCOMING / neomodel.match.EITHER @param **kwargs: positional keyword arguments specifying the constraints on the edges for traversals @return {list} related nodes via ERDDG Registration edges """ if direction == neomodel.match.OUTGOING: return self.ERDDGRegistrationConnectionsTo.match(**kwargs).all() elif direction == neomodel.match.INCOMING: return self.ERDDGRegistrationConnectionsFrom.match(**kwargs).all() else: return self.ERDDGRegistrationConnections.match(**kwargs).all() def get_connections_by_erddg_dependency(self, direction=neomodel.match.OUTGOING, **kwargs): """ @param {string} direction: neomodel.match.OUTGOING / neomodel.match.INCOMING / neomodel.match.EITHER @param **kwargs: positional keyword arguments specifying the constraints on the edges for traversals @return {list} related nodes via ERDDG Dependency edges """ if direction == neomodel.match.OUTGOING: return self.ERDDGDependencyConnectionsTo.match(**kwargs).all() elif direction == neomodel.match.INCOMING: return self.ERDDGDependencyConnectionsFrom.match(**kwargs).all() else: return self.ERDDGDependencyConnections.match(**kwargs).all()
class NewSomePerson(SomePerson): friends_with = neomodel.RelationshipTo("BaseOtherPerson", "FRIENDS_WITH", model=NewRelationship)