JOOL树结构
JOOL tree structure
我有一个文档集合:List listDocs。该文档具有以下形式的结构:
id, level, aoguid, parentguid, formalname, currstatus
。此结构允许您创建地址的树结构。即:国家 - 级别 1,城市 - 级别 2,街道 - 级别 3,依此类推直至级别 7。某些级别可能会或可能不会。我的任务:形成 json 包含完整地址和组成完整地址的部分数组。
{
"full Address": "Country city street house",
"parts": [
{
"id": 1,
"aoguid": 1,
"parentguid": 0,
"formalname": "country",
"currstatus": 0
},
{
"id": 2,
"aoguid": 2,
"parentguid": 1,
"formalname": "city",
"currstatus": 0
},
{
"id": 3,
"aoguid": 3,
"parentguid": 2,
"formalname": "street",
"currstatus": 0
},
{
"id": 4,
"aoguid": 4,
"parentguid": 3,
"formalname": "house",
"currstatus": 0
}
]
}
由于项目使用 mongoDb 而不是关系数据库,因此任务很复杂。但是我发现使用 JOOL 框架,你可以像 SQL 一样进行 JAVA 查询。我写了这段代码:
Seq<Document> seq1 = Seq.seq(listDocs).filter(
it -> isNull(it.get("currstatus")) || "0".equals(it.get("currstatus"))
);
Seq<Document> seq2 = seq1;
Seq<Document> seq3 = seq1;
Seq<Document> seq4 = seq1;
Seq<Document> seq5 = seq1;
Seq<Document> seq6 = seq1;
Seq<Document> seq7 = seq1;
seq1
.leftOuterJoin(seq2, (l1, l2) -> Objects.equals(l1.get("aoguid"), l2.get("parentguid")))
.leftOuterJoin(seq3, (l2, l3) -> Objects.equals(l2.v2.get("aoguid"), l3.get("parentguid")))
.leftOuterJoin(seq4, (l3, l4) -> Objects.equals(l3.v3.get("aoguid"), l4.get("parentguid")))
.leftOuterJoin(seq5, (l4, l5) -> Objects.equals(l4.v4.get("aoguid"), l5.get("parentguid")))
.leftOuterJoin(seq6, (l5, l6) -> Objects.equals(l5.v5.get("aoguid"), l6.get("parentguid")))
.leftOuterJoin(seq7, (l6, l7) -> Objects.equals(l6.v6.get("aoguid"), l7.get("parentguid")))
.parallel()
.forEach(it -> {
System.out.println("Some actions....");
});
但是这段代码无法编译。我该如何修复才能使一切正常?
找到解决方案:
public void saveES(List<Document> listDocs) {
Seq<Document> l1 = seq(listDocs).filter(
it -> ((Integer) it.get("currstatus") == 0)
);
l1
.flatMap(level_1 -> seq(listDocs)
.filter(level_2 -> isNull(level_2.get("currstatus")) || ((Integer) level_2.get("currstatus") == 0))
.filter(level_2 -> Objects.equals(level_1.get("aoguid"), level_2.get("parentguid")))
.onEmpty(null)
.map(level_2 -> tuple(level_1, level_2))
)
.flatMap(level_1_2 -> // return tuple(level_1_2.v1, level_1_2.v2, level_3);
seq(listDocs)
.filter(level_3 -> isNull(level_3.get("currstatus")) || ((Integer) level_3.get("currstatus") == 0))
.filter(level_3 -> Objects.equals(level_1_2.v2.get("aoguid"), level_3.get("parentguid")))
.onEmpty(null)
.map(level_1_2::concat)
)
.flatMap(level_1_2_3 -> seq(listDocs)
.filter(level_4 -> isNull(level_4.get("currstatus")) || ((Integer) level_4.get("currstatus") == 0))
.filter(level_4 -> Objects.equals(level_1_2_3.v2.get("aoguid"), level_4.get("parentguid")))
.onEmpty(null)
.map(level_1_2_3::concat)
)
.flatMap(level_1_2_3_4 -> seq(listDocs)
.filter(level_5 -> isNull(level_5.get("currstatus")) || ((Integer) level_5.get("currstatus") == 0))
.filter(level_5 -> Objects.equals(level_1_2_3_4.v2.get("aoguid"), level_5.get("parentguid")))
.onEmpty(null)
.map(level_1_2_3_4::concat)
)
.flatMap(level_1_2_3_4_5 -> seq(listDocs)
.filter(level_6 -> isNull(level_6.get("currstatus")) || ((Integer) level_6.get("currstatus") == 0))
.filter(level_6 -> Objects.equals(level_1_2_3_4_5.v2.get("aoguid"), level_6.get("parentguid")))
.onEmpty(null)
.map(level_1_2_3_4_5::concat)
)
.flatMap(level_1_2_3_4_5_6 -> seq(listDocs)
.filter(level_7 -> isNull(level_7.get("currstatus")) || ((Integer) level_7.get("currstatus") == 0))
.filter(level_7 -> Objects.equals(level_1_2_3_4_5_6.v2.get("aoguid"), level_7.get("parentguid")))
.onEmpty(null)
.map(level_1_2_3_4_5_6::concat)
)
.parallel()
.distinct()
.forEach(it -> {
log.info(
it.v1.get("formalname")
+ " -> " + it.v2.get("formalname")
+ " -> " + it.v3.get("formalname")
+ " -> " + it.v4.get("formalname")
+ " -> " + it.v5.get("formalname")
+ " -> " + it.v6.get("formalname")
+ " -> " + it.v7.get("formalname")
);
});
}
前面的解决方案也是正确的,可能对某些人有用,但我会列出我最终找到的解决方案。这是最终版本。
@Override
public void saveES(List<Document> listDocs) {
Seq<Document> root = seq(listDocs).filter(
it -> ((Integer) it.get("currstatus") == 0) && ((Integer) it.get("aolevel") == 1)
);
root
.leftOuterJoin(
seq(listDocs).filter(level_2 -> isNull(level_2.get("currstatus")) || ((Integer) level_2.get("currstatus") == 0)),
(a, b) -> checkObjects(a, b)
)
.leftOuterJoin(
seq(listDocs).filter(level_3 -> isNull(level_3.get("currstatus")) || ((Integer) level_3.get("currstatus") == 0)),
(a, b) -> checkObjects(a.v2, b)
)
.map(a -> a.v1.concat(a.v2))
.leftOuterJoin(
seq(listDocs).filter(level_4 -> isNull(level_4.get("currstatus")) || ((Integer) level_4.get("currstatus") == 0)),
(a, b) -> checkObjects(a.v3, b)
)
.map(a -> a.v1.concat(a.v2))
.leftOuterJoin(
seq(listDocs)
.filter(level_5 -> isNull(level_5.get("currstatus")) || (nonNull(level_5.get("currstatus")) && (Integer) level_5.get("currstatus") == 0)),
(a, b) -> checkObjects(a.v4, b)
)
.map(a -> a.v1.concat(a.v2))
.leftOuterJoin(
seq(listDocs).filter(level_6 -> isNull(level_6.get("currstatus")) || ((Integer) level_6.get("currstatus") == 0)),
(a, b) -> checkObjects(a.v5, b)
)
.map(a -> a.v1.concat(a.v2))
.leftOuterJoin(
seq(listDocs).filter(level_7 -> isNull(level_7.get("currstatus")) || ((Integer) level_7.get("currstatus") == 0)),
(a, b) -> checkObjects(a.v6, b)
)
.map(a -> a.v1.concat(a.v2))
.parallel()
.distinct()
.forEach(it -> {
List<Document> objects1 = (List<Document>) it.toList();
String full = objects1.stream()
.filter(Objects::nonNull)
.map(doc -> String.join(" ", doc.getOrDefault("shortname", "") + ".", (String) doc.get("formalname")))
.collect(Collectors.joining(" "));
List<Document> objects2 = (List<Document>) it.toList();
List<Entry> entryList = objects2.stream()
.filter(Objects::nonNull)
.map(doc -> Entry.builder()
.aoid((String) doc.getOrDefault("aoid", ""))
.aoGuid((String) doc.getOrDefault("aoguid", ""))
.code((String) doc.getOrDefault("code", ""))
.offName((String) doc.getOrDefault("offname", ""))
.parentGuid((String) doc.getOrDefault("parentguid", ""))
.shortName((String) doc.getOrDefault("shortname", ""))
.aoLevel((Integer) doc.getOrDefault("aolevel", ""))
.postalCode((String) doc.getOrDefault("postalcode", ""))
.build())
.collect(Collectors.toList());
log.info(full);
Address address = new Address(full, entryList);
searchService.save(address);
});
}
我有一个文档集合:List listDocs。该文档具有以下形式的结构:
id, level, aoguid, parentguid, formalname, currstatus
。此结构允许您创建地址的树结构。即:国家 - 级别 1,城市 - 级别 2,街道 - 级别 3,依此类推直至级别 7。某些级别可能会或可能不会。我的任务:形成 json 包含完整地址和组成完整地址的部分数组。
{
"full Address": "Country city street house",
"parts": [
{
"id": 1,
"aoguid": 1,
"parentguid": 0,
"formalname": "country",
"currstatus": 0
},
{
"id": 2,
"aoguid": 2,
"parentguid": 1,
"formalname": "city",
"currstatus": 0
},
{
"id": 3,
"aoguid": 3,
"parentguid": 2,
"formalname": "street",
"currstatus": 0
},
{
"id": 4,
"aoguid": 4,
"parentguid": 3,
"formalname": "house",
"currstatus": 0
}
]
}
由于项目使用 mongoDb 而不是关系数据库,因此任务很复杂。但是我发现使用 JOOL 框架,你可以像 SQL 一样进行 JAVA 查询。我写了这段代码:
Seq<Document> seq1 = Seq.seq(listDocs).filter(
it -> isNull(it.get("currstatus")) || "0".equals(it.get("currstatus"))
);
Seq<Document> seq2 = seq1;
Seq<Document> seq3 = seq1;
Seq<Document> seq4 = seq1;
Seq<Document> seq5 = seq1;
Seq<Document> seq6 = seq1;
Seq<Document> seq7 = seq1;
seq1
.leftOuterJoin(seq2, (l1, l2) -> Objects.equals(l1.get("aoguid"), l2.get("parentguid")))
.leftOuterJoin(seq3, (l2, l3) -> Objects.equals(l2.v2.get("aoguid"), l3.get("parentguid")))
.leftOuterJoin(seq4, (l3, l4) -> Objects.equals(l3.v3.get("aoguid"), l4.get("parentguid")))
.leftOuterJoin(seq5, (l4, l5) -> Objects.equals(l4.v4.get("aoguid"), l5.get("parentguid")))
.leftOuterJoin(seq6, (l5, l6) -> Objects.equals(l5.v5.get("aoguid"), l6.get("parentguid")))
.leftOuterJoin(seq7, (l6, l7) -> Objects.equals(l6.v6.get("aoguid"), l7.get("parentguid")))
.parallel()
.forEach(it -> {
System.out.println("Some actions....");
});
但是这段代码无法编译。我该如何修复才能使一切正常?
找到解决方案:
public void saveES(List<Document> listDocs) {
Seq<Document> l1 = seq(listDocs).filter(
it -> ((Integer) it.get("currstatus") == 0)
);
l1
.flatMap(level_1 -> seq(listDocs)
.filter(level_2 -> isNull(level_2.get("currstatus")) || ((Integer) level_2.get("currstatus") == 0))
.filter(level_2 -> Objects.equals(level_1.get("aoguid"), level_2.get("parentguid")))
.onEmpty(null)
.map(level_2 -> tuple(level_1, level_2))
)
.flatMap(level_1_2 -> // return tuple(level_1_2.v1, level_1_2.v2, level_3);
seq(listDocs)
.filter(level_3 -> isNull(level_3.get("currstatus")) || ((Integer) level_3.get("currstatus") == 0))
.filter(level_3 -> Objects.equals(level_1_2.v2.get("aoguid"), level_3.get("parentguid")))
.onEmpty(null)
.map(level_1_2::concat)
)
.flatMap(level_1_2_3 -> seq(listDocs)
.filter(level_4 -> isNull(level_4.get("currstatus")) || ((Integer) level_4.get("currstatus") == 0))
.filter(level_4 -> Objects.equals(level_1_2_3.v2.get("aoguid"), level_4.get("parentguid")))
.onEmpty(null)
.map(level_1_2_3::concat)
)
.flatMap(level_1_2_3_4 -> seq(listDocs)
.filter(level_5 -> isNull(level_5.get("currstatus")) || ((Integer) level_5.get("currstatus") == 0))
.filter(level_5 -> Objects.equals(level_1_2_3_4.v2.get("aoguid"), level_5.get("parentguid")))
.onEmpty(null)
.map(level_1_2_3_4::concat)
)
.flatMap(level_1_2_3_4_5 -> seq(listDocs)
.filter(level_6 -> isNull(level_6.get("currstatus")) || ((Integer) level_6.get("currstatus") == 0))
.filter(level_6 -> Objects.equals(level_1_2_3_4_5.v2.get("aoguid"), level_6.get("parentguid")))
.onEmpty(null)
.map(level_1_2_3_4_5::concat)
)
.flatMap(level_1_2_3_4_5_6 -> seq(listDocs)
.filter(level_7 -> isNull(level_7.get("currstatus")) || ((Integer) level_7.get("currstatus") == 0))
.filter(level_7 -> Objects.equals(level_1_2_3_4_5_6.v2.get("aoguid"), level_7.get("parentguid")))
.onEmpty(null)
.map(level_1_2_3_4_5_6::concat)
)
.parallel()
.distinct()
.forEach(it -> {
log.info(
it.v1.get("formalname")
+ " -> " + it.v2.get("formalname")
+ " -> " + it.v3.get("formalname")
+ " -> " + it.v4.get("formalname")
+ " -> " + it.v5.get("formalname")
+ " -> " + it.v6.get("formalname")
+ " -> " + it.v7.get("formalname")
);
});
}
前面的解决方案也是正确的,可能对某些人有用,但我会列出我最终找到的解决方案。这是最终版本。
@Override
public void saveES(List<Document> listDocs) {
Seq<Document> root = seq(listDocs).filter(
it -> ((Integer) it.get("currstatus") == 0) && ((Integer) it.get("aolevel") == 1)
);
root
.leftOuterJoin(
seq(listDocs).filter(level_2 -> isNull(level_2.get("currstatus")) || ((Integer) level_2.get("currstatus") == 0)),
(a, b) -> checkObjects(a, b)
)
.leftOuterJoin(
seq(listDocs).filter(level_3 -> isNull(level_3.get("currstatus")) || ((Integer) level_3.get("currstatus") == 0)),
(a, b) -> checkObjects(a.v2, b)
)
.map(a -> a.v1.concat(a.v2))
.leftOuterJoin(
seq(listDocs).filter(level_4 -> isNull(level_4.get("currstatus")) || ((Integer) level_4.get("currstatus") == 0)),
(a, b) -> checkObjects(a.v3, b)
)
.map(a -> a.v1.concat(a.v2))
.leftOuterJoin(
seq(listDocs)
.filter(level_5 -> isNull(level_5.get("currstatus")) || (nonNull(level_5.get("currstatus")) && (Integer) level_5.get("currstatus") == 0)),
(a, b) -> checkObjects(a.v4, b)
)
.map(a -> a.v1.concat(a.v2))
.leftOuterJoin(
seq(listDocs).filter(level_6 -> isNull(level_6.get("currstatus")) || ((Integer) level_6.get("currstatus") == 0)),
(a, b) -> checkObjects(a.v5, b)
)
.map(a -> a.v1.concat(a.v2))
.leftOuterJoin(
seq(listDocs).filter(level_7 -> isNull(level_7.get("currstatus")) || ((Integer) level_7.get("currstatus") == 0)),
(a, b) -> checkObjects(a.v6, b)
)
.map(a -> a.v1.concat(a.v2))
.parallel()
.distinct()
.forEach(it -> {
List<Document> objects1 = (List<Document>) it.toList();
String full = objects1.stream()
.filter(Objects::nonNull)
.map(doc -> String.join(" ", doc.getOrDefault("shortname", "") + ".", (String) doc.get("formalname")))
.collect(Collectors.joining(" "));
List<Document> objects2 = (List<Document>) it.toList();
List<Entry> entryList = objects2.stream()
.filter(Objects::nonNull)
.map(doc -> Entry.builder()
.aoid((String) doc.getOrDefault("aoid", ""))
.aoGuid((String) doc.getOrDefault("aoguid", ""))
.code((String) doc.getOrDefault("code", ""))
.offName((String) doc.getOrDefault("offname", ""))
.parentGuid((String) doc.getOrDefault("parentguid", ""))
.shortName((String) doc.getOrDefault("shortname", ""))
.aoLevel((Integer) doc.getOrDefault("aolevel", ""))
.postalCode((String) doc.getOrDefault("postalcode", ""))
.build())
.collect(Collectors.toList());
log.info(full);
Address address = new Address(full, entryList);
searchService.save(address);
});
}