20
|
1 package wikigraph;
|
|
2
|
|
3 import java.util.HashMap;
|
|
4
|
|
5 import org.neo4j.graphdb.Direction;
|
|
6 import org.neo4j.graphdb.GraphDatabaseService;
|
|
7 import org.neo4j.graphdb.Node;
|
|
8 import org.neo4j.graphdb.Path;
|
|
9 import org.neo4j.graphdb.Relationship;
|
|
10 import org.neo4j.graphdb.RelationshipType;
|
|
11 import org.neo4j.graphdb.traversal.Evaluators;
|
|
12 import org.neo4j.graphdb.traversal.TraversalDescription;
|
|
13 import org.neo4j.graphdb.traversal.Traverser;
|
|
14 import org.neo4j.kernel.Traversal;
|
|
15 import org.neo4j.tooling.GlobalGraphOperations;
|
|
16
|
|
17 public class LinkToNode {
|
|
18
|
|
19 GraphDatabaseService graphDb;
|
|
20 GlobalGraphOperations graphOpe;
|
|
21
|
21
|
22 public final static String PAGE_TITLE = "page_title";
|
|
23 public final static String PAGE_RANK = "page_rank";
|
25
|
24 private HashMap<String, Long> pageIdTable = new HashMap<String, Long>();
|
|
25 private HashMap<String, Double> pageRankTable = new HashMap<String, Double>();
|
|
26
|
|
27 private HashMap<String, WikiPage> wikiPageHash = new HashMap<String, WikiPage>();
|
24
|
28 private long AllNodeNumber;
|
23
|
29
|
25
|
30 private final double weight1 = 0.85;
|
|
31 private final double weight2 = 0.15;
|
|
32
|
20
|
33 public enum RelTypes implements RelationshipType {
|
|
34 HAS_LINK
|
|
35 }
|
|
36
|
|
37 LinkToNode(GraphDatabaseService graphDb) {
|
|
38 this.graphDb = graphDb;
|
|
39 this.graphOpe = GlobalGraphOperations.at(graphDb);
|
24
|
40 AllNodeNumber = 0;
|
20
|
41 }
|
25
|
42
|
21
|
43 LinkToNode(GraphDatabaseService graphDb, GlobalGraphOperations graphOpe) {
|
|
44 this.graphDb = graphDb;
|
|
45 this.graphOpe = graphOpe;
|
24
|
46 AllNodeNumber = 0;
|
21
|
47 }
|
|
48
|
20
|
49 void setGraphDb(GraphDatabaseService graphDb) {
|
|
50 this.graphDb = graphDb;
|
|
51 this.graphOpe = GlobalGraphOperations.at(graphDb);
|
24
|
52 AllNodeNumber = 0;
|
20
|
53 }
|
|
54
|
|
55 Long getId(String pageTitle) {
|
21
|
56 return pageIdTable.get(pageTitle);
|
|
57 }
|
25
|
58
|
21
|
59 boolean isHasLink(Relationship rel) {
|
|
60 return rel.isType(RelTypes.HAS_LINK);
|
20
|
61 }
|
25
|
62
|
20
|
63 private Node createNode() {
|
|
64 return graphDb.createNode();
|
|
65 }
|
25
|
66
|
20
|
67 private Node createNodeWithProperty(String key, Object value) {
|
|
68 Node node = createNode();
|
25
|
69 node.setProperty(key, value);
|
20
|
70 return node;
|
|
71 }
|
25
|
72
|
21
|
73 void initAllNodePageRank() {
|
|
74 for (Node node : graphOpe.getAllNodes()) {
|
25
|
75 setPageRank(node, 0.0);
|
21
|
76 }
|
|
77 }
|
25
|
78
|
21
|
79 String getPageTitle(Node node) {
|
|
80 return (String) node.getProperty(PAGE_TITLE);
|
|
81 }
|
25
|
82
|
|
83 Double getPageRank(Node node) {
|
|
84 return (Double) node.getProperty(PAGE_RANK);
|
21
|
85 }
|
25
|
86
|
|
87 Node createNodeWithPageTitle(String pageTitle) {
|
20
|
88 Node node = createNodeWithProperty(PAGE_TITLE, pageTitle);
|
25
|
89 pageIdTable.put(pageTitle, node.getId());
|
20
|
90 return node;
|
|
91 }
|
25
|
92
|
|
93 Node setPageRank(Node node, Double rank) {
|
21
|
94 node.setProperty(PAGE_RANK, rank);
|
|
95 return node;
|
|
96 }
|
25
|
97
|
20
|
98 Node getNode(String name) {
|
21
|
99 long id = pageIdTable.get(name);
|
20
|
100 return graphDb.getNodeById(id);
|
|
101 }
|
|
102
|
25
|
103 Node getNode(int nodeId) {
|
|
104 return graphDb.getNodeById(nodeId);
|
|
105 }
|
|
106
|
|
107 void setRelationship(Node node1, Node node2, RelTypes type) {
|
20
|
108 node1.createRelationshipTo(node2, type);
|
|
109 }
|
|
110
|
|
111 void setHasLink(Node node1, Node node2) {
|
|
112 setRelationship(node1, node2, RelTypes.HAS_LINK);
|
|
113 }
|
25
|
114
|
24
|
115 long searchAllNodes() {
|
|
116 AllNodeNumber = 0;
|
25
|
117 for (Node n : graphOpe.getAllNodes()) {
|
|
118 if (n.hasProperty(PAGE_TITLE) || n.hasProperty(PAGE_RANK)) {
|
24
|
119 WikiPage wiki = new WikiPage(n);
|
25
|
120 pageIdTable.put((String) n.getProperty(PAGE_TITLE), n.getId());
|
|
121 pageRankTable.put((String) n.getProperty(PAGE_TITLE),
|
|
122 (Double) n.getProperty(PAGE_RANK));
|
26
|
123 wiki.setInHasLink(computeInHasLink(n));
|
|
124 wiki.setOutHasLink(computeOutHasLink(n));
|
25
|
125 wikiPageHash.put((String) n.getProperty(PAGE_TITLE), wiki);
|
21
|
126 AllNodeNumber++;
|
|
127 }
|
20
|
128 }
|
21
|
129 return AllNodeNumber;
|
20
|
130 }
|
25
|
131
|
|
132 void searchRegiNodes(Node n) {
|
|
133
|
|
134 if (n.hasProperty(PAGE_TITLE) || n.hasProperty(PAGE_RANK)) {
|
|
135 WikiPage wiki = new WikiPage(n);
|
|
136 pageIdTable.put((String) n.getProperty(PAGE_TITLE), n.getId());
|
|
137 pageRankTable.put((String) n.getProperty(PAGE_TITLE),
|
|
138 (Double) n.getProperty(PAGE_RANK));
|
26
|
139 wiki.setInHasLink(computeInHasLink(n));
|
|
140 wiki.setOutHasLink(computeOutHasLink(n));
|
25
|
141 wikiPageHash.put((String) n.getProperty(PAGE_TITLE), wiki);
|
|
142 AllNodeNumber++;
|
|
143 }
|
|
144 }
|
|
145
|
|
146 HashMap<String, WikiPage> getWikiPageHash() {
|
24
|
147 return wikiPageHash;
|
23
|
148 }
|
25
|
149
|
|
150 HashMap<String, Long> getPageIdTable() {
|
21
|
151 return pageIdTable;
|
20
|
152 }
|
21
|
153
|
25
|
154 HashMap<String, Double> getPageRankTable() {
|
21
|
155 return pageRankTable;
|
25
|
156 }
|
|
157
|
20
|
158 public void printAllNodes() {
|
25
|
159 for (Node n : graphOpe.getAllNodes()) {
|
|
160 System.out.println("ID=" + n.getId());
|
|
161 for (String key : n.getPropertyKeys()) {
|
20
|
162 System.out.println(key + "=" + n.getProperty(key));
|
|
163 }
|
25
|
164 Iterable<Relationship> relIter = n
|
|
165 .getRelationships(RelTypes.HAS_LINK);
|
|
166 for (Relationship rel : relIter) {
|
20
|
167 System.out.println(rel);
|
|
168 }
|
|
169 System.out.println("--");
|
|
170 }
|
|
171
|
|
172 }
|
|
173
|
24
|
174 private Traverser getTraverser(final Node node, final Direction rel) {
|
25
|
175 TraversalDescription td = Traversal.description().breadthFirst()
|
|
176 .relationships(RelTypes.HAS_LINK, rel)
|
|
177 .evaluator(Evaluators.excludeStartPosition());
|
|
178 return td.traverse(node);
|
|
179
|
24
|
180 }
|
25
|
181
|
|
182 public Traverser getOutHasLinkTraverser(final Node node) {
|
24
|
183 return getTraverser(node, Direction.OUTGOING);
|
|
184 }
|
25
|
185
|
|
186 public Traverser getInHasLinkTraverser(final Node node) {
|
24
|
187 return getTraverser(node, Direction.INCOMING);
|
|
188 }
|
25
|
189
|
24
|
190 public long computeOutHasLink(final Node node) {
|
|
191 long count = 0;
|
|
192 Traverser hasLinkTraverser = getOutHasLinkTraverser(node);
|
|
193 for (Path hasLinkPath : hasLinkTraverser) {
|
25
|
194 if (hasLinkPath.length() > 1)
|
|
195 break;
|
24
|
196 count++;
|
|
197 }
|
|
198 return count;
|
21
|
199 }
|
|
200
|
24
|
201 public long computeInHasLink(final Node node) {
|
|
202 long count = 0;
|
|
203 Traverser hasLinkTraverser = getInHasLinkTraverser(node);
|
|
204 for (Path hasLinkPath : hasLinkTraverser) {
|
25
|
205 if (hasLinkPath.length() > 1)
|
|
206 break;
|
24
|
207 count++;
|
|
208 }
|
|
209 return count;
|
20
|
210 }
|
24
|
211
|
26
|
212 public void printOutHasLink(final Node node, int depth) {
|
20
|
213 int numberOfLinkPages = 0;
|
26
|
214 String output = node.getProperty(PAGE_TITLE) + " outHasLink pages:";
|
|
215 System.out.println(output);
|
25
|
216 Traverser hasLinkTraverser = getOutHasLinkTraverser(node);
|
|
217 for (Path hasLinkPath : hasLinkTraverser) {
|
26
|
218 if (depth < hasLinkPath.length()) break;
|
|
219 String depthOutput = "At depth " + hasLinkPath.length() + " => "
|
|
220 + hasLinkPath.endNode().getProperty(PAGE_TITLE);
|
|
221 System.out.println(depthOutput);
|
20
|
222 numberOfLinkPages++;
|
|
223 }
|
26
|
224 String numOutput = "Number of link pages: " + numberOfLinkPages;
|
|
225 System.out.println(numOutput);
|
|
226 }
|
|
227
|
|
228 public void printInHasLink(final Node node, int depth) {
|
|
229 int numberOfLinkPages = 0;
|
|
230 String output = node.getProperty(PAGE_TITLE) + " inHasLink pages:";
|
20
|
231 System.out.println(output);
|
26
|
232 Traverser hasLinkTraverser = getInHasLinkTraverser(node);
|
|
233 for (Path hasLinkPath : hasLinkTraverser) {
|
|
234 if (depth < hasLinkPath.length()) break;
|
|
235 String depthOutput = "At depth " + hasLinkPath.length() + " => "
|
|
236 + hasLinkPath.endNode().getProperty(PAGE_TITLE);
|
|
237 System.out.println(depthOutput);
|
|
238 numberOfLinkPages++;
|
|
239 }
|
|
240 String numOutput = "Number of link pages: " + numberOfLinkPages + "\n";
|
|
241 System.out.println(numOutput);
|
20
|
242 }
|
24
|
243
|
25
|
244 public double computePageRank(Node node) {
|
|
245 double sum = 0;
|
|
246 double pageRank = 0;
|
24
|
247 String title = getPageTitle(node);
|
|
248 WikiPage wiki = wikiPageHash.get(title);
|
25
|
249
|
24
|
250 Traverser hasLinkTraverser = getInHasLinkTraverser(node);
|
25
|
251 for (Path hasLinkPath : hasLinkTraverser) {
|
|
252 if (hasLinkPath.length() > 1)
|
|
253 break;
|
24
|
254 Node n = hasLinkPath.endNode();
|
25
|
255 sum += (Double) n.getProperty(PAGE_RANK);
|
24
|
256 }
|
26
|
257 if (wiki.getOutHasLink() == 0) {
|
25
|
258 pageRank = (double) ((double) 1 / AllNodeNumber * weight2);
|
|
259 } else {
|
26
|
260 pageRank = (double) ((double)sum / wiki.getOutHasLink() * weight1)
|
25
|
261 + (double) ((double) 1 / AllNodeNumber * weight2);
|
|
262 }
|
|
263
|
24
|
264 wiki.setRank(pageRank);
|
|
265 node.setProperty(PAGE_RANK, pageRank);
|
|
266 return pageRank;
|
|
267 }
|
26
|
268
|
|
269 public void printNodeInfo(int nodeId) {
|
|
270 Node node = graphDb.getNodeById(nodeId);
|
|
271 String title = getPageTitle(node);
|
|
272 double rank = getPageRank(node);
|
|
273 long inHasLink = computeInHasLink(node);
|
|
274 long outHasLink = computeOutHasLink(node);
|
|
275
|
|
276 System.out.println("id:"+nodeId+" title:"+title+" rank:"+rank);
|
|
277 System.out.println("inHasLink:"+inHasLink+" outHasLink:"+outHasLink);
|
|
278
|
|
279 printInHasLink(node, 1);
|
|
280 printOutHasLink(node, 1);
|
|
281
|
|
282 }
|
25
|
283
|
20
|
284 }
|