view src/wikigraph/LinkToNode.java @ 24:71fe482aaf32 draft

fix LinkToNode.java
author one
date Tue, 28 Aug 2012 15:27:35 +0900
parents 21902773e530
children fbf0cf550b06
line wrap: on
line source

package wikigraph;

import java.util.HashMap;

import org.neo4j.graphdb.Direction;
import org.neo4j.graphdb.GraphDatabaseService;
import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.Path;
import org.neo4j.graphdb.Relationship;
import org.neo4j.graphdb.RelationshipType;
import org.neo4j.graphdb.traversal.Evaluators;
import org.neo4j.graphdb.traversal.TraversalDescription;
import org.neo4j.graphdb.traversal.Traverser;
import org.neo4j.kernel.Traversal;
import org.neo4j.tooling.GlobalGraphOperations;

import wikigraph.Neo4jTest.RelTypes;


public class LinkToNode {

	GraphDatabaseService graphDb;
	GlobalGraphOperations graphOpe;

	public final static String PAGE_TITLE = "page_title";
	public final static String PAGE_RANK = "page_rank";
	private HashMap<String,Long> pageIdTable = new HashMap<String,Long>();
	private HashMap<String,Long> pageRankTable = new HashMap<String,Long>();
	
	private HashMap<String,WikiPage> wikiPageHash = new HashMap<String,WikiPage>();
	private long AllNodeNumber;

	public enum RelTypes implements RelationshipType {
		HAS_LINK
	}

	LinkToNode(GraphDatabaseService graphDb) {
		this.graphDb = graphDb;
		this.graphOpe = GlobalGraphOperations.at(graphDb);
		AllNodeNumber = 0;
	}
	
	LinkToNode(GraphDatabaseService graphDb, GlobalGraphOperations graphOpe) {
		this.graphDb = graphDb;
		this.graphOpe = graphOpe;
		AllNodeNumber = 0;
	}

	void setGraphDb(GraphDatabaseService graphDb) {
		this.graphDb = graphDb;
		this.graphOpe = GlobalGraphOperations.at(graphDb);
		AllNodeNumber = 0;
	}

	Long getId(String pageTitle) {
		return pageIdTable.get(pageTitle);
	}
	
	boolean isHasLink(Relationship rel) {
		return rel.isType(RelTypes.HAS_LINK);
	}
	
	private Node createNode() {
		return graphDb.createNode();
	}
	
	private Node createNodeWithProperty(String key, Object value) {
		Node node = createNode();
		node.setProperty(key,value);
		return node;
	}
	
	void initAllNodePageRank() {
		for (Node node : graphOpe.getAllNodes()) {
			setPageRank(node, 0);
		}
	}
	
	
	String getPageTitle(Node node) {
		return (String) node.getProperty(PAGE_TITLE);
	}
	
	Long getPageRank(Node node) {
		return (Long) node.getProperty(PAGE_RANK);
	}
	
	Node createNodeWithPageTitle(String pageTitle){
		Node node = createNodeWithProperty(PAGE_TITLE, pageTitle);
		pageIdTable.put(pageTitle,  node.getId());
		return node;
	}
	
	Node setPageRank(Node node, long rank) {
		node.setProperty(PAGE_RANK, rank);
		return node;
	}
	
	Node getNode(String name) {
		long id = pageIdTable.get(name);
		return graphDb.getNodeById(id);
	}
	
	void setRelationship(Node node1, Node node2, RelTypes type) { 
		node1.createRelationshipTo(node2, type);
	}

	void setHasLink(Node node1, Node node2) {
		setRelationship(node1, node2, RelTypes.HAS_LINK);
	}
	
	long searchAllNodes() {
		AllNodeNumber = 0;
		for (Node n: graphOpe.getAllNodes()) {
			if (n.hasProperty(PAGE_TITLE)) {
				WikiPage wiki = new WikiPage(n);
				wikiPageHash.put((String)n.getProperty(PAGE_TITLE), wiki);
				pageIdTable.put((String)n.getProperty(PAGE_TITLE), n.getId());
				pageRankTable.put((String)n.getProperty(PAGE_TITLE), (Long) n.getProperty(PAGE_RANK));
				wiki.setInLink(computeInHasLink(n));
				wiki.setOutLink(computeOutHasLink(n));
				
				AllNodeNumber++;
			}
		}
		return AllNodeNumber;
	}
	
	HashMap<String,WikiPage> getWikiPageHash() {
		return wikiPageHash;
	}
	
	HashMap<String,Long> getPageIdTable() {
		return pageIdTable;
	}

	HashMap<String,Long> getPageRankTable() {
		return pageRankTable;
	}	
	
	public void printAllNodes() {
		for (Node n: graphOpe.getAllNodes()) {
			System.out.println("ID="+ n.getId());
			for (String key: n.getPropertyKeys()) {
				System.out.println(key + "=" + n.getProperty(key));
			}
			Iterable<Relationship> relIter = n.getRelationships(RelTypes.HAS_LINK);
			for (Relationship rel : relIter ) {
				System.out.println(rel);
			}
			System.out.println("--");
		}

	}

	private Traverser getTraverser(final Node node, final Direction rel) {
		TraversalDescription td = Traversal.description()
				.breadthFirst()
				.relationships( RelTypes.HAS_LINK, rel )
				.evaluator( Evaluators.excludeStartPosition());
		return td.traverse( node );
		
	}
	
	public Traverser getOutHasLinkTraverser( final Node node) {
		return getTraverser(node, Direction.OUTGOING);
	}
	
	public Traverser getInHasLinkTraverser( final Node node) {
		return getTraverser(node, Direction.INCOMING);
	}
	
	public long computeOutHasLink(final Node node) {
		long count = 0;
		Traverser hasLinkTraverser = getOutHasLinkTraverser(node);
		for (Path hasLinkPath : hasLinkTraverser) {
			if (hasLinkPath.length() > 1) break;
			count++;
		}
		return count;
	}

	public long computeInHasLink(final Node node) {
		long count = 0;
		Traverser hasLinkTraverser = getInHasLinkTraverser(node);
		for (Path hasLinkPath : hasLinkTraverser) {
			if (hasLinkPath.length() > 1) break;
			count++;
		}
		return count;
	}


	public void searchHasLinkOut(final Node node) {
		int numberOfLinkPages = 0;
		String output = node.getProperty(PAGE_TITLE) + " have link pages:\n";
		Traverser hasLinkTraverser = getOutHasLinkTraverser( node );
		for ( Path hasLinkPath : hasLinkTraverser) {
			output += "At depth " + hasLinkPath.length() + " => "
					+ hasLinkPath.endNode()
						.getProperty(PAGE_TITLE) + "\n";
			numberOfLinkPages++;
		}
		output += "Number of link pages: " + numberOfLinkPages + "\n";
		System.out.println(output);
	}

	public long computePageRank(Node node) {
		long sum = 0;
		long pageRank = 0;
		String title = getPageTitle(node);
		WikiPage wiki = wikiPageHash.get(title);
		
		Traverser hasLinkTraverser = getInHasLinkTraverser(node);
		for (Path hasLinkPath: hasLinkTraverser) {
			if (hasLinkPath.length() > 1) break;
			Node n = hasLinkPath.endNode();
			sum += (Long)n.getProperty(PAGE_RANK);
		}
		pageRank = (long) (sum/wiki.getInLink() * 0.85 
				+ 1 / AllNodeNumber * 0.15);
				
		wiki.setRank(pageRank);
		node.setProperty(PAGE_RANK, pageRank);
		return pageRank;
	}
	
	
}