Ejemplo n.º 1
0
class WordVector(object):
    _instances = {}

    @classmethod
    def get_instance(cls, graph_tag='default'):
        if graph_tag not in cls._instances:
            cls._instances[graph_tag] = WordVector(graph_tag)
        return cls._instances[graph_tag]

    def __init__(self, graph_tag):
        self.g = Graph(graph_tag)

    def save_vertex(self, vector_id, properties):
        """
        保存词向量

        :param vector_id: 词向量 ID
        :param properties: 词向量属性
        :return: 保存结果
        """
        return self.g.save_vertex("word_vector", str(vector_id), properties)

    def save_edge(self, vector_id, related_id, related_type, properties):
        """
        保存词向量关系

        :param vector_id: 词向量 ID
        :param related_id: 相关联的顶点 ID
        :param related_type: 关系类型
        :param properties: 关系属性
        :return: 保存结果
        """
        return self.g.save_edge(related_type, str(related_id), str(vector_id),
                                properties)
Ejemplo n.º 2
0
class AddProperty(object):
    _instances = {}

    @classmethod
    def get_instance(cls, graph_tag='default'):
        if graph_tag not in cls._instances:
            cls._instances[graph_tag] = AddProperty(graph_tag)
        return cls._instances[graph_tag]

    def __init__(self, graph_tag):
        self.g = Graph(graph_tag)
        self.mock_data()

    def mock_data(self):
        # 创建一个 person 类型的顶点
        dsl = """
            g.addV('person')
        """

        ret = self.g.exec_dsl(dsl).result().next()
        print(ret)

    def run(self):
        # 给 person 类型的顶点添加 name 和 age 属性
        dsl = """
            g.V().hasLabel("person").
                property('name', name).
                property('age', age)
        """
        bindings = {"name": "stephen", "age": "25"}

        self.g.exec_dsl(dsl, bindings)
        Common.get_instance().show_graph()
Ejemplo n.º 3
0
class Singer(object):
    _instances = {}

    @classmethod
    def get_instance(cls, graph_tag='default'):
        if graph_tag not in cls._instances:
            cls._instances[graph_tag] = Singer(graph_tag)
        return cls._instances[graph_tag]

    def __init__(self, graph_tag):
        self.g = Graph(graph_tag)

    def save_vertex(self, singer_id, properties):
        """
        保存歌手

        :param singer_id: 歌手 ID
        :param properties: 歌手属性
        :return: 保存结果
        """
        return self.g.save_vertex("singer", str(singer_id), properties)

    def save_edge(self, singer_id, related_id, related_type, properties):
        """
        保存歌手关系

        :param singer_id: 歌手 ID
        :param related_id: 相关联的顶点 ID
        :param related_type: 关系类型
        :param properties: 关系属性
        :return: 保存结果
        """
        return self.g.save_edge(related_type, str(singer_id), str(related_id),
                                properties)
Ejemplo n.º 4
0
class AddEdge(object):
    _instances = {}

    @classmethod
    def get_instance(cls, graph_tag='default'):
        if graph_tag not in cls._instances:
            cls._instances[graph_tag] = AddEdge(graph_tag)
        return cls._instances[graph_tag]

    def __init__(self, graph_tag):
        self.g = Graph(graph_tag)
        self.mock_data()

    def mock_data(self):
        # 创建两个 person 类型的顶点并设置 id 和 name
        dsl = """
            g.addV('person').
                property(id, uid_1).
                property('name', name_1).
              addV('person').
                property(id, uid_2).
                property('name', name_2)
        """
        bindings = {
            "uid_1": "1",
            "name_1": "marko",
            "uid_2": "2",
            "name_2": "stephen"
        }

        ret = self.g.exec_dsl(dsl, bindings).result().next()
        print(ret)

    def run(self):
        # 给两个 person 顶点添加 knows 类型的边
        dsl = """
            g.V(from_uid).addE('knows').to(V(to_uid)).
                property(id, edge_id)
        """
        bindings = {"from_uid": "1", "to_uid": "2", "edge_id": "1-knows-2"}

        ret = self.g.exec_dsl(dsl, bindings).result().next()
        print(ret)

        Common.get_instance().show_graph()
Ejemplo n.º 5
0
class And(object):
    _instances = {}

    @classmethod
    def get_instance(cls, graph_tag='default'):
        if graph_tag not in cls._instances:
            cls._instances[graph_tag] = And(graph_tag)
        return cls._instances[graph_tag]

    def __init__(self, graph_tag):
        self.g = Graph(graph_tag)
        self.mock_data()

    def mock_data(self):
        # 创建两个 person 类型的顶点
        dsl = """
            g.addV('person').
                property(id, uid_1).
                property('age', age_1).
              addV('person').
                property(id, uid_2).
                property('age', age_2)
        """
        bindings = {"uid_1": 1, "age_1": 20, "uid_2": 2, "age_2": 25}

        ret = self.g.exec_dsl(dsl, bindings).result().next()
        print(ret)

    def run(self):
        dsl = """
            g.V().has('age', inside(start_1, end_1)).
                and().
                has('age', outside(start_2, end_2)).
            values('age')
        """
        # (10, 30) 与 (-∞, 15) U (20, +∞) 的交集 => 25
        bindings = {'start_1': 10, 'end_1': 30, 'start_2': 15, 'end_2': 20}

        vertex_list = self.g.exec_dsl(dsl, bindings).result().next()
        print("ans: {}".format(vertex_list))

        Common.get_instance().show_graph()
Ejemplo n.º 6
0
class AddVertex(object):
    _instances = {}

    @classmethod
    def get_instance(cls, graph_tag='default'):
        if graph_tag not in cls._instances:
            cls._instances[graph_tag] = AddVertex(graph_tag)
        return cls._instances[graph_tag]

    def __init__(self, graph_tag):
        self.g = Graph(graph_tag)

    def run(self):
        """ 创建一个 person 类型的顶点并设置 id 和 name """
        dsl = "g.addV('person').property(id, uid).property('name', name)"
        bindings = {"name": "stephen", "uid": "1"}

        ret = self.g.exec_dsl(dsl, bindings).result().next()
        print(ret)

        Common.get_instance().show_graph()
Ejemplo n.º 7
0
class Utils(object):
    _instances = {}

    @classmethod
    def get_instance(cls, graph_tag='default'):
        if graph_tag not in cls._instances:
            cls._instances[graph_tag] = Utils(graph_tag)
        return cls._instances[graph_tag]

    def __init__(self, graph_tag):
        self.g = Graph(graph_tag)

    @staticmethod
    def format_graph_fields(graph_data):
        format_data = {}
        for k, v in graph_data.items():
            format_data[str(k)] = v[0] if type(v) == list else v

        format_data['id'] = format_data['T.id']
        format_data['label'] = format_data['T.label']

        del format_data['T.id']
        del format_data['T.label']

        return format_data

    def graph_visualization(self, size=100):
        """
        将图数据库中的数据可视化

        :param size: 起始点的数量(歌曲)
        :return:
        """
        dsl = """
            g.V().hasLabel('song').limit(size).as('SONGS').
                project('song', 'user', 'singer').
                    by(select('SONGS').valueMap(true)).
                    by(select('SONGS').in('favorite_song').valueMap(true).fold()).
                    by(select('SONGS').in('create_song').valueMap(true).fold())
        """
        bindings = {"size": size}
        callback = self.g.query_dsl(dsl, bindings)

        relation = {"vertex": [], "edge": []}

        for ret in callback.result():
            for data in ret:
                song = self.format_graph_fields(data["song"])
                relation["vertex"].append(song)

                user_list = []
                for user in data["user"]:
                    user = self.format_graph_fields(user)
                    user_list.append(user)
                    relation["edge"].append({
                        "from": user["id"],
                        "to": song["id"],
                        "type": "favorite_song"
                    })
                relation["vertex"].extend(user_list)

                singer_list = []
                for singer in data["singer"]:
                    singer = self.format_graph_fields(singer)
                    singer_list.append(singer)
                    relation["edge"].append({
                        "from": singer["id"],
                        "to": song["id"],
                        "type": "create_song"
                    })
                relation["vertex"].extend(singer_list)

        result = {
            "type": "force",
            "categories": [{
                "name": "用户"
            }, {
                "name": "歌曲"
            }, {
                "name": "歌手"
            }],
            "nodes": [],
            "links": []
        }
        category_index = {"user": 0, "song": 1, "singer": 2}

        vertex_index = {}

        for i, vertex in enumerate(relation["vertex"]):
            result["nodes"].append({
                "name": vertex["name"],
                "value": 1,
                "category": category_index[vertex["label"]]
            })
            vertex_index[vertex["id"]] = i

        for edge in relation["edge"]:
            result["links"].append({
                "source": vertex_index[edge["from"]],
                "target": vertex_index[edge["to"]]
            })

        return json.dumps(result)
Ejemplo n.º 8
0
 def __init__(self, graph_tag):
     self.g = Graph(graph_tag)
Ejemplo n.º 9
0
 def __init__(self, graph_tag):
     self.g = Graph(graph_tag)
     self.mock_data()
Ejemplo n.º 10
0
class Common(object):
    _instances = {}
    WAITING_TIME = 1

    @classmethod
    def get_instance(cls, graph_tag='default'):
        if graph_tag not in cls._instances:
            cls._instances[graph_tag] = Common(graph_tag)
        return cls._instances[graph_tag]

    def __init__(self, graph_tag):
        self.g = Graph(graph_tag)

    def show_graph(self):
        time.sleep(Common.WAITING_TIME)

        vertex_list = self._get_vertex()
        edge_list = self._get_edge()

        data = {}
        if vertex_list:
            data["vertex"] = vertex_list
        if edge_list:
            data["edge"] = edge_list

        print(json.dumps(data, indent=4, sort_keys=True))
        print("-" * 50)

    def _get_vertex(self):
        dsl = "g.V().valueMap(true)"
        callback = self.g.exec_dsl(dsl)

        result = []
        for ret in callback.result():
            for vertex in ret:
                data = self._format_graph_fields(vertex)
                result.append(data)

        return result

    def _get_edge(self):
        dsl = "g.E().valueMap(true)"
        callback = self.g.exec_dsl(dsl)

        result = []
        for ret in callback.result():
            for edge in ret:
                data = self._format_graph_fields(edge)
                result.append(data)

        return result

    @staticmethod
    def _format_graph_fields(graph_data):
        format_data = {}
        for k, v in graph_data.items():
            format_data[str(k)] = v[0] if type(v) == list else v

        format_data['id'] = format_data['T.id']
        format_data['label'] = format_data['T.label']

        del format_data['T.id']
        del format_data['T.label']

        return format_data
Ejemplo n.º 11
0
class User(object):
    _instances = {}

    @classmethod
    def get_instance(cls, graph_tag='default'):
        if graph_tag not in cls._instances:
            cls._instances[graph_tag] = User(graph_tag)
        return cls._instances[graph_tag]

    def __init__(self, graph_tag):
        self.g = Graph(graph_tag)

    def find_similar_user(self, uid, top_n=3):
        """
        找到与当前用户兴趣相近的用户

        :param uid: 用户 ID
        :return: 兴趣相近的用户信息
        """
        dsl = """
            g.V(uid).as('v1').
                out('favorite_song').in('favorite_song').dedup().where(neq('v1')).as('v2').
                project('v1', 'v2', 'v1n', 'v2n').
                    by(select('v1')).
                    by(select('v2')).
                    by(select('v1').out('favorite_song').fold()).
                    by(select('v2').out('favorite_song').fold()).
                as('q1').
                project('v1', 'v2', 'i', 'u').
                    by(select('v1')).
                    by(select('v2')).
                    by(select('v1n').as('n').
                       select('q1').select('v2n').unfold().
                          where(within('n')).
                          count()).
                    by(union(select('v1n').
                             select('q1').select('v2n')).unfold().
                       dedup().count()).
                project('v1', 'v2', 'jaccard').
                    by(select('v1').valueMap(true)).
                    by(select('v2').valueMap(true)).
                    by(math('i/u')).order().by(select('jaccard'), desc).
                limit(top_n)
        """
        bindings = {"uid": uid, "top_n": top_n}
        callback = self.g.query_dsl(dsl, bindings)

        result = []

        for ret in callback.result():
            for data in ret:
                v2_vertex = Utils.format_graph_fields(data["v2"])
                result.append({
                    "uid": v2_vertex["id"],
                    "name": v2_vertex["name"],
                    "jaccard_score": round(data["jaccard"], 5)
                })
        return result

    def save_vertex(self, uid, properties):
        """
        保存用户

        :param uid: 用户 ID
        :param properties: 用户属性
        :return: 保存结果
        """
        return self.g.save_vertex("user", str(uid), properties)

    def save_edge(self, uid, related_id, related_type, properties):
        """
        保存用户关系

        :param uid: 用户 ID
        :param related_id: 相关联的顶点 ID
        :param related_type: 关系类型
        :param properties: 关系属性
        :return: 保存结果
        """
        return self.g.save_edge(related_type, str(uid), str(related_id),
                                properties)
Ejemplo n.º 12
0
class Aggregate(object):
    _instances = {}

    @classmethod
    def get_instance(cls, graph_tag='default'):
        if graph_tag not in cls._instances:
            cls._instances[graph_tag] = Aggregate(graph_tag)
        return cls._instances[graph_tag]

    def __init__(self, graph_tag):
        self.g = Graph(graph_tag)
        self.mock_data()

    def mock_data(self):
        # 创建两个 person 类型的顶点和两个 song 类型的顶点
        dsl = """
            g.addV('person').
                property(id, uid_1).
                property('name', name_1).
              addV('person').
                property(id, uid_2).
                property('name', name_2).
              addV('song').
                property(id, song_id_1).
                property('name', song_name_1).
              addV('song').
                property(id, song_id_2).
                property('name', song_name_2)
        """
        bindings = {
            "uid_1": "u1",
            "name_1": "marko",
            "uid_2": "u2",
            "name_2": "stephen",
            "song_id_1": "s1",
            "song_name_1": "song-A",
            "song_id_2": "s2",
            "song_name_2": "song-B"
        }

        ret = self.g.exec_dsl(dsl, bindings).result().next()
        print(ret)

        # 添加三条边: marko-like->song-A;stephen-like-song-A;stephen-like-song-B
        dsl = """
            g.V(uid_1).addE('like').to(V(song_id_1)).
                property(id, edge_id_1).
              V(uid_2).addE('like').to(V(song_id_1)).
                property(id, edge_id_2).
              V(uid_2).addE('like').to(V(song_id_2)).
                property(id, edge_id_3)
        """
        bindings = {
            "uid_1": "u1",
            "name_1": "marko",
            "uid_2": "u2",
            "name_2": "stephen",
            "song_id_1": "s1",
            "song_name_1": "song-A",
            "song_id_2": "s2",
            "song_name_2": "song-B",
            "edge_id_1": "u1-like-song-A",
            "edge_id_2": "u2-like-song-A",
            "edge_id_3": "u2-like-song-B"
        }

        ret = self.g.exec_dsl(dsl, bindings).result().next()
        print(ret)

    def run(self):
        # 找到与 marko 有共同兴趣的人还喜欢哪些 marko 没喜欢的歌曲
        dsl = """
            g.V(uid_1).out('like').aggregate('x').
                in('like').out('like').
                where(without('x')).
                values('name')
        """
        bindings = {"uid_1": "u1"}

        self.g.exec_dsl(dsl, bindings)
        Common.get_instance().show_graph()