나는 또한이 질문에 대한 답을 알아야 할 필요가 있으므로 여기서는 해결책이있다.
코드를 사용자 정의해야하고 몇 가지 개선 사항이있을 것이라고 확신합니다.이 샘플 답변에 해당하는 경우 적절하게 의견을 말하십시오.
해결 방법은 재귀를 지원하는 Foxx Microservice를 사용하고 트리를 작성하는 것입니다. 내가 가지고있는 문제는 루핑 경로를 둘러싼 것이지만 최대 심도 한계를 구현하여이 예를 10 단계로 하드 코딩했습니다.
장소를 만들기
- 새 폴더를 만듭니다 (예 : 재귀 트리) 루트 디렉토리
- 장소에 파일
manifest.json
및 index.js
스크립트 디렉토리에있는 setup.js
파일
- 그런 다음이 세 파일로 새 zip 파일을 만듭니다 (예 :).)
- ArangoDB 관리 콘솔로 이동
- 서비스 | 서비스 추가
- 적절한 마운트 포인트를 입력하십시오./내/트리
우편 탭
- 클릭
- 만든
Foxx.zip
파일 드래그, 그것은 문제없이 작성해야
- 오류가 발생하면,
myItems
및 myConnections
이 존재하지 않는 컬렉션, 그래프를 확인 myGraph
은 존재하지 않습니다. 샘플 데이터로 생성하려고하기 때문입니다.
- 그런 다음 ArangoDB 관리 콘솔 인 서비스 | API에/내/트리
- 클릭
- 은/트리/{rootId}
- 이 ItemA의 rootId 매개 변수를 제공하고 당신은 제공된 루트 ID에서 결과를 볼 수
- '을 그것을 밖으로 시도'를 클릭를 확장 . rootId에 아이가없는 경우 rootId가 존재하지 않는 경우
는
, 그것은 rootId 루핑 한 것은 값, 그것은까지 중첩 반환 '포함'경우가 '포함'에 대한 하늘의 배열을 돌려줍니다 아무것도 을 반환하지 않습니다 심도 한계, 나는 이것을 멈추는 더 깨끗한 방법이 있었으면 좋겠다. 여기
는 세 개의 파일이 있습니다 : (스크립트 폴더에 위치하는) setup.js : (루트 폴더에 위치하는) 'use strict';
const db = require('@arangodb').db;
const graph_module = require("org/arangodb/general-graph");
const itemCollectionName = 'myItems';
const edgeCollectionName = 'myConnections';
const graphName = 'myGraph';
if (!db._collection(itemCollectionName)) {
const itemCollection = db._createDocumentCollection(itemCollectionName);
itemCollection.save({_key: "ItemA" });
itemCollection.save({_key: "ItemB" });
itemCollection.save({_key: "ItemC" });
itemCollection.save({_key: "ItemD" });
itemCollection.save({_key: "ItemE" });
if (!db._collection(edgeCollectionName)) {
const edgeCollection = db._createEdgeCollection(edgeCollectionName);
edgeCollection.save({_from: itemCollectionName + '/ItemA', _to: itemCollectionName + '/ItemB'});
edgeCollection.save({_from: itemCollectionName + '/ItemB', _to: itemCollectionName + '/ItemC'});
edgeCollection.save({_from: itemCollectionName + '/ItemB', _to: itemCollectionName + '/ItemD'});
edgeCollection.save({_from: itemCollectionName + '/ItemD', _to: itemCollectionName + '/ItemE'});
}
const graphDefinition = [
{
"collection": edgeCollectionName,
"from":[itemCollectionName],
"to":[itemCollectionName]
}
];
const graph = graph_module._create(graphName, graphDefinition);
}
mainfest.json :
{
"engines": {
"arangodb": "^3.0.0"
},
"main": "index.js",
"scripts": {
"setup": "scripts/setup.js"
}
}
(루트 폴더에 위치하는) 하는 index.js :
'use strict';
const createRouter = require('@arangodb/foxx/router');
const router = createRouter();
const joi = require('joi');
const db = require('@arangodb').db;
const aql = require('@arangodb').aql;
const recursionQuery = function(itemId, tree, depth) {
const result = db._query(aql`
FOR d IN myItems
FILTER d._id == ${itemId}
LET contains = (
FOR c IN 1..1 OUTBOUND ${itemId} GRAPH 'myGraph' RETURN { "_id": c._id }
)
RETURN MERGE({"_id": d._id}, {"contains": contains})
`);
tree = result._documents[0];
if (depth < 10) {
if ((result._documents[0]) && (result._documents[0].contains) && (result._documents[0].contains.length > 0)) {
for (var i = 0; i < result._documents[0].contains.length; i++) {
tree.contains[i] = recursionQuery(result._documents[0].contains[i]._id, tree.contains[i], depth + 1);
}
}
}
return tree;
}
router.get('/tree/:rootId', function(req, res) {
let myResult = recursionQuery('myItems/' + req.pathParams.rootId, {}, 0);
res.send(myResult);
})
.response(joi.object().required(), 'Tree of child nodes.')
.summary('Tree of child nodes')
.description('Tree of child nodes underneath the provided node.');
module.context.use(router);
는 이제 FO를 호출 할 수 있습니다 xx Microservice API 끝점. 전체 트리를 반환하는 rootId를 제공합니다. 매우 빠릅니다.
ItemA이의 출력 예는 다음과 같습니다
{
"_id": "myItems/ItemA",
"contains": [
{
"_id": "myItems/ItemB",
"contains": [
{
"_id": "myItems/ItemC",
"contains": []
},
{
"_id": "myItems/ItemD",
"contains": [
{
"_id": "myItems/ItemE",
"contains": []
}
]
}
]
}
]
}
해당 항목 B가 두 아이, ItemC 및 ItemD이 포함되어 볼 수 있습니다, 다음 ItemD도 ItemE이 포함되어 있습니다.
ArangoDB AQL이 FOR v, e, p IN 1..100 OUTBOUND 'abc/def' GRAPH 'someGraph'
스타일 쿼리에서 가변 깊이 경로 처리를 향상시킬 때까지 기다릴 수 없습니다. 커스텀 방문자는 3.x에서의 사용을 권장하지 않았지만 패스의 정점 깊이에 대해 와일드 카드 쿼리를 처리하거나 경로 통과시 prune
또는 exclude
스타일 명령을 처리 할 때 강력한 것으로 대체되지 않았습니다.
단순화 할 수 있다면 의견이나 의견을 보내고 싶습니다.
'for v, e, p for 1..3 inbound'를 참조하고'p'를 반환하는 몇 가지 관련 기술. 좀더 구체적인 것을 원한다면'p.vertices [0], p.vertices [1], p.vertices [2]'를 사용할 수 있습니다. 거기에서'p'가 이미 계층 적 형식으로되어 있지만 원하는 값을 표시하도록 구조를 구성 할 수 있습니다. –
최대 중첩 깊이를 알고 있습니까? 아니면 예측할 수없는 재귀적인 것입니까? –
결과가 왜 계층 적이어야합니까? 결과 집합에서 중복을 방지하기로되어 있습니까? – CoDEmanX