org.unlaxer.jaddress.gremlin.GremlinUtil Maven / Gradle / Ivy
package org.unlaxer.jaddress.gremlin;
import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.has;
import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.out;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal;
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;
import org.apache.tinkerpop.gremlin.structure.Vertex;
import org.unlaxer.jaddress.entity.standard.建物階層;
import org.unlaxer.jaddress.entity.standard.郵便番号;
import org.unlaxer.jaddress.entity.standard.階層要素;
import org.unlaxer.jaddress.parser.AddressContext;
import org.unlaxer.jaddress.parser.AddressElement;
import org.unlaxer.jaddress.parser.BlockHierarchyResolver.BlockPatternResolverResult;
import org.unlaxer.jaddress.parser.BuildingHierarchyResolver.BuildingHierarchyResolverResult;
import org.unlaxer.jaddress.parser.BuildingHierarchyResolver2.BuildingHierarchyResolverResult2;
import org.unlaxer.jaddress.parser.CharacterKind;
import org.unlaxer.jaddress.parser.CharacterKinds;
import org.unlaxer.jaddress.parser.SeparatorKind;
public class GremlinUtil {
private GraphTraversalSource g;
public GremlinUtil(GraphTraversalSource g) {
super();
this.g = g;
}
public static enum Edge {
include
}
public static enum Field {
label, //
element, //
value, //
level, //
lead, //
tail,//
}
/**
* property support array Gremlin = OK (VertexPropertyFeatures) Neo4j = NG
* (https://neo4j.com/docs/cypher-manual/current/syntax/values/)
*
* 使えても、検索、マージは面倒になる
*
* @param addressContext
*/
public void create(AddressContext addressContext) {
List vertexs = new ArrayList<>();
List needEdges = new ArrayList<>();
List nodes = convertToNodes(addressContext);
nodes.forEach(n -> {
GraphTraversal g0 = g.V().hasLabel(n.label)//
.has(Field.element.name(), n.element)//
.has(Field.value.name(), n.value)//
.has(Field.level.name(), n.level)//
.has(Field.lead.name(), n.lead)//
.has(Field.tail.name(), n.tail)//
;
Vertex v1;
if (g0.hasNext()) {
v1 = g0.next();
needEdges.add(false);
} else {
g0.iterate();
v1 = g.addV(n.label)//
.property(Field.element.name(), n.element)//
.property(Field.value.name(), n.value)//
.property(Field.level.name(), n.level)//
.property(Field.lead.name(), n.lead)//
.property(Field.tail.name(), n.tail)//
.next();
needEdges.add(true);
}
vertexs.add(v1);
});
for (int i = 1; i < vertexs.size(); i++) {
if (needEdges.get(i - 1) || needEdges.get(i)) {
g.V(vertexs.get(i - 1)).addE(Edge.include.name()).to(vertexs.get(i)).next();
}
}
}
private List convertToNodes(AddressContext addressContext) {
List nodes = new ArrayList<>();
List labels = new ArrayList<>();
labels.add(addressContext.zip.hyphonated);
nodes.add(new NodeElement(addressContext.zip));
addressContext.results().right.ifPresent(result -> {
result.get().stream().forEach(as -> {
as.get().forEach(addressElement -> {
String value = addressElement.asString();
if (value != null && !value.isBlank()) {
labels.add(value);
nodes.add(new NodeElement(labels, addressElement));
}
});
});
});
return nodes;
}
@SuppressWarnings("unchecked")
public BlockPatternResolverResult searchBlockPattern(郵便番号 zip, AddressElement town) {
BlockPatternResolverResult ret = new BlockPatternResolverResult();
createGraphTraversal(zip, town).valueMap(Field.element.name(), Field.value.name()).toStream().forEach(map -> {
String a = (String) ((List) (map.get(Field.element.name()))).get(0);
String b = (String) ((List) (map.get(Field.value.name()))).get(0);
// System.out.println(a + "=" + b);
CharacterKinds cs = new CharacterKinds(CharacterKind.stringAndCharacterKindsOf(b));
ret.add(階層要素.valueOf(a), cs);
});
return ret;
}
private GraphTraversal createGraphTraversal(郵便番号 zip, AddressElement town) {
GraphTraversal t1 = g.V().hasLabel(zip.hyphonated)
.until(has(Field.value.name(), town.asString()).has(Field.level.name(), town.階層要素().level))
.repeat(out());
GraphTraversal t2 = t1.repeat(out()).emit();
return t2;
}
@SuppressWarnings("unchecked")
public BuildingHierarchyResolverResult2 searchBuildings2(郵便番号 zip, Map<階層要素, AddressElement> addressMap) {
SortedMap<階層要素, CharacterKinds> ret1 = new TreeMap<>();
createGraphTraversal(zip, addressMap).valueMap(Field.element.name(), Field.value.name()).toStream()
.forEach(map -> {
String a = (String) ((List) (map.get(Field.element.name()))).get(0);
String b = (String) ((List) (map.get(Field.value.name()))).get(0);
CharacterKinds cs = new CharacterKinds(CharacterKind.stringAndCharacterKindsOf(b));
階層要素 k = 階層要素.valueOf(a);
ret1.put(k, cs);
});
Set buildingNames = createGraphTraversal(zip, addressMap).has(Field.level.name(), 9)
.values(Field.value.name()).toStream().map(e -> (String) e).distinct().collect(Collectors.toSet());
return new BuildingHierarchyResolverResult2(ret1, buildingNames);
}
public AddressElement createAddressElement(String word, 階層要素 _階層要素) {
return new AddressElement(word, _階層要素, SeparatorKind.domainSpecificSeparator,
SeparatorKind.domainSpecificSeparator);
}
public BuildingHierarchyResolverResult searchBuildings(郵便番号 zip, Map<階層要素, AddressElement> addressMap) {
Set<階層要素> elements = createGraphTraversal(zip, addressMap).values(Field.element.name()).toStream()
.map(p -> 階層要素.valueOf((String) p)).distinct().collect(Collectors.toSet());
Set buildingNames = createGraphTraversal(zip, addressMap).has(Field.level.name(), 9)
.values(Field.value.name()).toStream().map(e -> (String) e).distinct().collect(Collectors.toSet());
return new BuildingHierarchyResolverResult(建物階層.from階層要素(elements), buildingNames);
}
private GraphTraversal createGraphTraversal(郵便番号 zip, Map<階層要素, AddressElement> addressMap) {
GraphTraversal t = g.V().hasLabel(zip.hyphonated).out(Edge.include.name());
階層要素[] keys = new 階層要素[addressMap.size()];
addressMap.keySet().toArray(keys);
for (int i = 0; i < addressMap.size(); i++) {
AddressElement e = addressMap.get(keys[i]);
t.has(Field.value.name(), e.asString()).has(Field.element.name(), e.階層要素().name());
if (addressMap.size() - 1 != i) {
t.out(Edge.include.name());
}
}
t.repeat(out()).emit();
return t;
}
public void truncate() {
long count = g.V().count().next();
for (int i = 0; i < count / 1000 + 1; i++) {
g.V().limit(1000).drop().iterate();
}
count = g.E().count().next();
for (int i = 0; i < count / 1000 + 1; i++) {
g.E().limit(1000).drop().iterate();
}
}
public Stream searchNextValues(String label) {
return g.V().hasLabel(label).out(Edge.include.name()).values(Field.value.name()).toStream()
.map(v -> v.toString()).distinct();
}
public String count() {
return String.format("V=%d, E=%d", g.V().count().next(), g.E().count().next());
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy