Example #1
0
def shortestPathWeight(query, rootNode):
    stop = stopwords.words('english')
    query = query.split()
    g = Graph()
    weight = 0
    for term in query:
        pathSet = set()
        if term not in stop:
            result = g.cypher.execute("MATCH (n:NP) where str(n.phrase) =~ '(?i).*"+term+".*' return n")
            if result:
                for item in result:
                    uri = item.n.graph.uri + item.n.ref + '/path'
                    headers = {
                                    'Accept': 'application/json',
                                    'Content-Type': 'application/json; charset=UTF-8'
                                }
                    target = urlparse(uri.string)
                    method = 'POST'
                    body = {
                                "to": str(rootNode.graph.uri+rootNode.ref),
                                "max_depth": 20,
                                "relationships" : {
                                    "type" : "DEPENDS"
                                  },
                                  "algorithm" : "shortestPath"
                            }
                    body = json.dumps(body)
                    h = http.Http()
                    response, content = h.request(target.geturl(), method, body, headers)
                    try:
                        data = json.loads(content.decode())
                        relationships = data['relationships']
                        for rel in relationships:
                            relId = rel[rel.rfind('/')+1:]
                            rel = g.relationship(relId)
                            pathSet.add(rel.properties['path_id'])
                        weight = weight + harmonicProduct(len(pathSet))
                    except:
                        pass
    return weight
Example #2
0
class GraphDB:

    def __init__(self,username, password, server, port):
        '''
            username = '******'
            password = '******'
            server = 'localhost'
            port = '7474'
        '''
        self.username = username
        self.password = password
        self.server = server
        self.port = port
        self.con_url = 'http://'+username+':'+password+'@'+server+':'+port+'/db/data/'
        self.graph = Graph(self.con_url)

         ##TODO: move these to constants.py when IPYTHON not required
        self.metaprops = {
        'RESOLVEDUUID':'_resolvedWithUUID_',
        'RESOLVEDRELID':'_resolvedWithRELID_',
        'RESOLVEDHENID':'_resolvedWithHENID_', ##for hyper edge node
        'RESOLVEDHERID':'_resolvedWithHERID_', ##for hyper edge relation
        }

    #Done: Multiple each time want to ask something
    #Else: works on old data only
    ##Wont use this
    def getGraph(self):
        return self.graph

    ##NOT TO BE USED
    #this is how we use the intenal ids of the graph
    ##should we use it?? most people say no
    ## anyways, made the method for future use
    ## Use : getNodeByInternalId(graph, 152)
    def getNodeByInternalId(self,id):
        a = self.graph.node(id) #getting by id given internally by neo4j
        a.pull()
        return a


    ##NOT TO BE USED
    ## similar to above
    ## Use : getRelByInternalId(graph, 4)
    def getRelByInternalId(self,id):
        a = self.graph.relationship(id)
        a.pull()
        return a

    def getNodeByUniqueID(self, uniquelabel, idName, idVal, isIDString=False):
        ##TODO: move uuid to props
        query = "match (n:"+uniquelabel+" {"
        if isIDString:
            query = query+ idName+":'"+str(idVal)+"'}) return n"
        else:
            query = query+ idName+":"+str(idVal)+"}) return n"
        rc = self.graph.cypher.execute(query)
        return rc[0][0]


    def getRelationByUniqueID(self, idName, idVal, isIDString=False):
        ##TODO: move uuid to props
        query = "match ()-[r {"
        if isIDString:
            query = query+ idName+":'"+str(idVal)+"'}]->() return r"
        else:
            query = query+ idName+":"+str(idVal)+"}]->() return r"
        rc = self.graph.cypher.execute(query)
        return rc[0][0]


    def isPropList(self, node, prop):
        return type(node[prop]) is list

    ##has a counter brother in nexusapis flask app
    def isValidNonMetaProp(self, propname):
        if propname[0]=='_' or propname[-1]=='_':
            return False
        return True

    ##copy meta = True
    def copyNode(self, node, copymeta = True, exceptions = []):
        #exceptions are the props that should be included no matter what, if they have underscore or not!
        naya = Node()
        for label in node.labels:
            naya.labels.add(label)
        for prop in exceptions:
            if prop in node.properties:
                naya[prop] = node[prop]
        for prop in node.properties:
            if not copymeta:
                if self.isValidNonMetaProp(prop):
                    naya[prop] = node[prop]
            else:
                naya[prop] = node[prop]
        return naya

    def copyNodeAsItIs(self, node):
        return self.copyNode(node)
        #         naya = Node()
        #         for label in node.labels:
        #             naya.labels.add(label)
        #         for prop in node.properties:
        #             naya[prop] = node[prop]
        #         return naya

    def copyNodeWithoutMeta(self, node, exceptions=[]):
        return self.copyNode(node, copymeta = False, exceptions = exceptions)

    def copyRelation(self, rel, copymeta = True, rel_exceptions = [], node_exceptions = []):
        start_node  = ''
        end_node = ''

        if not copymeta:
            start_node = self.copyNodeWithoutMeta(rel.start_node, exceptions = node_exceptions)
            end_node = self.copyNodeWithoutMeta(rel.end_node, exceptions = node_exceptions)
        else:
            start_node = self.copyNodeAsItIs(rel.start_node)
            end_node = self.copyNodeAsItIs(rel.end_node)

        reltype = rel.type
        nayarel = Relationship(start_node, reltype, end_node)

        for prop in rel_exceptions:
            if prop in rel.properties:
                nayarel[prop] = rel[prop]
        for prop in rel.properties:
            if not copymeta:
                if self.isValidNonMetaProp(prop):
                    nayarel[prop] = rel[prop]
            else:
                nayarel[prop] = rel[prop]
        return nayarel

    def copyRelationAsItIs(self, rel):
        return self.copyRelation(rel)
        #         start_node = g.copyNodeAsItIs(rel.start_node)
        #         end_node = g.copyNodeAsItIs(rel.end_node)
        #         reltype = rel.type
        #         naya = Relationship(start_node, reltype, end_node)
        #         for prop in rel.properties:
        #             naya[prop] = rel[prop]
        #         return naya

    def copyObjectAsItIs(self, kind, obj):
        if kind == 'relation':
            return self.copyRelationAsItIs(obj)
        if kind == 'node':
            return self.copyNodeAsItIs(obj)
        return None

    def copyRelationWithoutMeta(self, rel, rel_exceptions = [], node_exceptions = []):
        return self.copyRelation(rel, copymeta = False, rel_exceptions = rel_exceptions, node_exceptions = node_exceptions)

    def getDirectlyConnectedEntities(self, idname, idval, uniquelabel='', isIDString = True):
        '''
            given idname like uuid, henid and uniquelabel like entity or hyperedgenode
            gives us the connected nodes of this node
            returns nodes which have uuids only
            note: works for hyperedgenodes only for now
            #TODO: extend so that this info can be shown on view page
        '''
        from app.constants import LABEL_ENTITY
        invertedComma = ''
        if isIDString:
            invertedComma = "'"
        query = "match (n:%s {%s:%s%s%s})-[]-(p:%s) return distinct(p)"
        query = query %(uniquelabel, idname, invertedComma, idval, invertedComma, LABEL_ENTITY)
        results = self.graph.cypher.execute(query)
        enlist = []
        for res in results:
            enlist.append(res[0])
        return enlist

    def getDirectlyConnectedRelations(self, idname, idval, uniquelabel='', isIDString = True,outgoing=True):
        '''
            given idname like uuid, henid and uniquelabel like entity or hyperedgenode
            gives us the connected nodes of this node
            returns nodes which have uuids only
            note: works for hyperedgenodes only for now
            #TODO: extend so that this info can be shown on view page
        '''
        from app.constants import LABEL_ENTITY
        invertedComma = ''
        if isIDString:
            invertedComma = "'"
        query = ''
        if outgoing:
            query = "match (n:%s {%s:%s%s%s})-[p]->(:%s) return distinct(p)"
        else:
            query = "match (n:%s {%s:%s%s%s})<-[p]-(:%s) return distinct(p)"
        query = query %(uniquelabel, idname, invertedComma, idval, invertedComma, LABEL_ENTITY)
        results = self.graph.cypher.execute(query)
        rellist = []
        for res in results:
            rellist.append(res[0])
        return rellist


    ##example of some text input: (n154346:businessperson:person:politician {name:"Anita",uuid:1234})
    ##Usage: deserializeNode('''(n154346:businessperson:person:politician {name:"Anita",uuid:1234})''')
    def deserializeNode(self, nodeText):
        pos =  nodeText.find(' ')

        #get the labels in a set
        startText = nodeText[1:pos]
        allLabels = startText.split(':')[1:]
        allLabels =  set(allLabels) #set is imp

        #get the props in a dict
        endText = nodeText[pos+1:-1]
        endTextWB = endText[1:-1]
        #print endText
        #print endTextWB
        propList = endTextWB.split(",")
        propsDict = {}
        for x in propList:
            propval = x.split(":")
            #for handling the single inverted comma problem
            prop = propval[0]
            val = propval[1]
            if val[0]=="'" and val[-1]=="'":
                val=val[1:-1]
            #for handling the double inverted comma problem
            if val[0]=='"' and val[-1]=='"':
                val=val[1:-1]
            propsDict[prop]=val


        #print propsDict

        #creating the node from parsedText
        node = Node()
        for x in allLabels:
            node.labels.add(x)
        for x in propsDict:
            node[x] = propsDict[x]
        print node
        return node
        ##MAJOR TODO:
        ##work to do add a form where they can create a node
        #get a node's page by uuid
        #also get node's relations in form of graph, embed that graph
        #edit a node
        #edit a relation
        #dlete a node
        #delete a relation
        #moderate any change --> how to do that --> where will this lie!
        #Note the diff between now and then

    def generateSearchData(self, idname, idval, isIDString, getList=False):

        from app.utils.commonutils import Utils

        comp = self.getNodeByUniqueID('entity', idname, idval, isIDString)
        ##comp is the node in question

        keywords = ''
        labels = ''
        aliases_to_return = ''

        if getList:
            keywords = []
            labels = []
            aliases_to_return = []

        quotes = "" ##the ' wre  reudundant from beginning

        for prop in comp.properties:
            ##begins with underscore ignore
            if prop!='uuid' and prop!='aliases' and prop[0]!='_':
                currvalue = str(comp.properties[prop])
                currvalue = Utils.processString(currvalue)
                if prop!='uuid' and len(currvalue)>3:
                    if not getList:
                        keywords = keywords + quotes +currvalue + quotes+","
                    else:
                        keywords.append(currvalue)

        neighbours  = self.getDirectlyConnectedEntities(idname, idval,
            'entity', isIDString)

        for rel in neighbours:
            currvalue = str(rel.properties['name'])
            currvalue = Utils.processString(currvalue)
            if not getList:
                keywords = keywords + quotes +currvalue + quotes+","
            else:
                keywords.append(rel.properties['name'])
        # keywords = keywords + '"'

        # labels = ''
        for label in list(comp.labels):
            if not getList:
                labels = labels + quotes + label + quotes+","
            else:
                labels.append(label)
        # labels=labels + '"'

        aliases = []

        if aliases is None or aliases == []:
            aliases = [comp['name']]

        ##patch
        from app.utils.commonutils import Utils
        aliases = Utils.merge(comp['aliases'],comp['name'])

        print 'allllllllllllllaaaaaaaa'
        print aliases
        # if type(aliases) is not list: ##fix for just one aliases, though wont be req
        #     aliases = [aliases]
        # ##patch

        for alias in aliases:
            if not getList:
                aliases_to_return = aliases_to_return + quotes +str(Utils.processString(alias)) + quotes+","
            else:
                aliases_to_return.append(alias)
        # aliases =aliases_to_return + '"'

        # name = '"'+comp.properties['name']+'"'
        name = comp.properties['name']
        print 'aliases_to_return, aliases, aliases_to_return'
        print aliases_to_return
        print keywords

        if len(keywords)>50:
            keywords=keywords[:50]
        return name, labels, aliases_to_return, keywords