티스토리 뷰
LARQ는 ARQ와 Lucene으로 이루어져 SPARQL 쿼리에 텍스트 검색을 위해 사용된다.
사용패턴은 크게 문자열 인덱스 생성과 Subject 인덱스 생성이 있겠다.
문자열 인덱스 생성은 트리플에 포함되어있는 string을 Lucene을 통해 인덱스를 생성하고
생성된 인덱스에 검색 문자열과 매칭이 되는 string을 반환해 준다.
반면에 Subject 인덱스 생성은 문자열 인덱스 생성과 유사하나
반환하는 값이 그 문자열이 포함된 string이 아니라
그 string의 Subject 자원이다.
실제 사용을 위해 인덱스를 생성하는 작업부터 테스트를 해보았다.
인덱스의 생성은 Model 자체를 읽는 것과
Model의 Statement를 읽어서 생성하는 방식이 있다.
1. 먼저 Jena Model을 로딩하여 인덱스를 생성하도록 시도하였다.
//파일을 model로 로딩
Model model = ModelFactory.createDefaultModel();
FileInputStream fis = new FileInputStream(inputFileName);
InputStreamReader in = new InputStreamReader(fis, "UTF-8");
model.read(in,"");
// indexFolder는 인덱스 생성 파일 생성 장소
IndexBuilderSubject larqBuilder = new IndexBuilderSubject(new File(indexFolder));
model.register(larqBuilder);
//model을 읽어 인덱스 생성
FileManager.get().readModel(model, file.getAbsolutePath());
larqBuilder.closeWriter() ;
model.unregister(larqBuilder);
테스트 결과 model을 로딩하는 방식은 백만단위의 트리플까지는 큰 문제 없이 잘 수행되었으나
천만 단위가 넘어가는 8천만 정도의 트리플을 로딩하고자 하니
메모리 부족 문제를 만나게 된다.
작은 양의 트리플에는 무난하게 사용할 수 있겠으나 대용량에서는 다른 방법이 필요하겠다.
2. 두번째는 TDB를 활용하여 인덱스를 생성하도록 시도하였다.
TDBLoader를 통해 file로 대용량의 트리플을 저장시키고 LARQ index를 생성하는 방식이다.
TDBLoader에서는 대용량 데이터에 대해서 index를 생성하는 시간이 오래 걸리기 때문에
data load 기능만 사용하고 index 생성 기능은 삭제하였다.
private void load(){
FileOps.clearDirectory(directory);
Log.setCmdLogging() ;
TDB.getContext().set(SystemTDB.symFileMode, "direct");
DatasetGraph dsg = TDBFactory.createDatasetGraph(directory);
GraphTDB graph = (GraphTDB) dsg.getDefaultGraph();
ArrayList<String> fileList =loadFile(fileFolder);
//4번째 인자
// true => 데이터 load 후 index 생성
// false => 데이터만 load
TDBLoader.load(graph, fileList, true, false);
graph.close();
dsg.close();
TDB.closedown();
}
public void makeIndex(){
Dataset ds = TDBFactory.createDataset(tdbDirectory);
Model model = ds.getDefaultModel();
//인덱스 폴더 정리
FileOps.clearDirectory(indexFolder);
IndexBuilderSubject larqBuilder = new IndexBuilderSubject(new File(indexFolder));
StmtIterator iter = model.listStatements();
larqBuilder.indexStatements(iter);
larqBuilder.closeWriter();
ds.close();
}
테스트 결과는 첫번째 시도에서 발생하는 메모리 문제나 시간의 문제가 해결되었으며
대용량의 트리플(8천8백만건)에 대한 인덱스 생성이 무난히 수행되었다.
시간적인 부분에 대해서는 TDB로딩에 약 1시간 정도가 소요되고
LARQ index 생성은 약 5시간 정도 소요가 되었다.
이제 index를 생성하였으나
본연의 목적인 생성된 index를 통해 SPARQL 쿼리 테스트를 시도하였다.
public static void main(String[] args) {
Model model = ModelFactory.createDefaultModel();
IndexBuilderString larqBuilder = new IndexBuilderString(new File(indexFolder));
IndexLARQ index = larqBuilder.getIndex();
larqBuilder.closeWriter();
// Search for
String searchString = "고구려" ;
String queryString = StrUtils.strjoin("\n",
"PREFIX pf: <http://jena.hpl.hp.com/ARQ/property#>",
"PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>" ,
"prefix kdp: <http://data.kdata.kr/property/> ",
"PREFIX : <http://example/>" ,
"SELECT * {" ,
" ?lit pf:textMatch '+"+searchString+"'.",
"}") ;
performQuery(model, index, queryString) ;
index.close() ;
}
public static void performQuery(Model model, IndexLARQ index, String queryString) {
// Make globally available
LARQ.setDefaultIndex(index) ;
Query query = QueryFactory.create(queryString) ;
// query.serialize(System.out) ;
// System.out.println();
QueryExecution qExec = QueryExecutionFactory.create(query, model) ;
// LARQ.setDefaultIndex(qExec.getContext(), index) ;
ResultSetFormatter.out(System.out, qExec.execSelect(), query) ;
qExec.close() ;
}
기존 SPARQL에 텍스트 검색을 하려고 하면 시간소요가 엄청나게 발생하는데
LARQ를 활용하니 index를 생성하고 그 index를 통해 검색을 수행하니
만족할 만한 상당한 속도가 나왔다.
index 생성 시간만 조금 단축된다면 좋겠지만 index 생성 후 SPARQL 사용에는 만족할 만 하다..
'O:::Jena 다루기' 카테고리의 다른 글
O_6. Jena TDB에 Select하기 (0) | 2019.12.16 |
---|---|
O_5. Triple 단위를 Statement 단위로 변경하기 (0) | 2019.12.13 |
O_4. TDB 에 적재된 내용 확인 (0) | 2019.12.11 |
O_2. Jena TDBLoader Test (0) | 2013.01.18 |
O_1. SPARQL 실행 (0) | 2012.12.05 |
- Total
- Today
- Yesterday
- 지식 그래프
- LOD
- Neo4j
- RDF 변환
- rdfox
- RDF
- Linked Data
- 트리플
- TopBraid Composer
- 트리플 변환
- Ontology
- 온톨로지
- pyvis
- 스프링부트
- django
- Knowledge Graph
- property graph
- 사이퍼
- TDB
- TBC
- cypher
- 타임리프
- networkx
- stardog
- 지식그래프
- 장고
- Thymeleaf
- neosemantics
- 그래프 데이터베이스
- sparql
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |