package org.fastcatsearch.job.internal; import java.io.IOException; import org.fastcatsearch.common.io.Streamable; import org.fastcatsearch.error.SearchError; import org.fastcatsearch.error.ServerErrorCode; import org.fastcatsearch.exception.FastcatSearchException; import org.fastcatsearch.ir.IRService; import org.fastcatsearch.ir.io.DataInput; import org.fastcatsearch.ir.io.DataOutput; import org.fastcatsearch.ir.query.InternalSearchResult; import org.fastcatsearch.ir.query.Metadata; import org.fastcatsearch.ir.query.Query; import org.fastcatsearch.ir.query.QueryModifier; import org.fastcatsearch.ir.search.CollectionHandler; import org.fastcatsearch.ir.search.CollectionSearcher; import org.fastcatsearch.ir.search.HitElement; import org.fastcatsearch.ir.search.PkScore; import org.fastcatsearch.ir.search.PkScoreList; import org.fastcatsearch.job.Job; import org.fastcatsearch.query.QueryMap; import org.fastcatsearch.query.QueryParser; import org.fastcatsearch.service.ServiceManager; import org.fastcatsearch.transport.vo.StreamableInternalSearchResult; public class InternalSearchJob extends Job implements Streamable { private static final long serialVersionUID = 4998297114497342795L; private QueryMap queryMap; private boolean forMerging; public InternalSearchJob(){} public InternalSearchJob(QueryMap queryMap){ this.queryMap = queryMap; } public InternalSearchJob(QueryMap queryMap, boolean forMerging){ this.queryMap = queryMap; this.forMerging = forMerging; } @Override public JobResult doRun() throws FastcatSearchException { Query q = QueryParser.getInstance().parseQuery(queryMap); String collectionId = queryMap.collectionId(); try { Metadata meta = q.getMeta(); QueryModifier queryModifier = meta.queryModifier(); //쿼리모디파이. if (queryModifier != null) { q = queryModifier.modify(collectionId, q); meta = q.getMeta(); } logger.debug("q > {}", q); InternalSearchResult result = null; IRService irService = ServiceManager.getInstance().getService(IRService.class); //Not Exist in Cache if(result == null){ CollectionHandler collectionHandler = irService.collectionHandler(collectionId); if(collectionHandler == null){ throw new SearchError(ServerErrorCode.COLLECTION_NOT_FOUND, collectionId); } Query boostQuery = q.getBoostQuery(); PkScoreList pkScoreList = null; if(boostQuery != null) { try { String boostKeyword = boostQuery.getMeta().getUserData("KEYWORD"); pkScoreList = new PkScoreList(boostKeyword); String boostCollectionId = boostQuery.getMeta().collectionId(); CollectionHandler boostCollectionHandler = irService.collectionHandler(boostCollectionId); CollectionSearcher boostCollectionSearcher = boostCollectionHandler.searcher(); InternalSearchResult r = boostCollectionSearcher.searchInternal(boostQuery, forMerging); for (HitElement e : r.getHitElementList()) { if (e == null) { continue; } //FIXME 첫번째 필드가 id이다. logger.debug("e.docNo() > {}", e.docNo()); logger.debug("field > {}", boostCollectionSearcher.requestDocument(e.docNo()).get(1)); String id = boostCollectionSearcher.requestDocument(e.docNo()).get(1).toString(); int score = e.score(); pkScoreList.add(new PkScore(id, score)); } } catch(Throwable t) { logger.error("error while boosting query > " + boostQuery, t); } } result = collectionHandler.searcher().searchInternal(q, forMerging, pkScoreList); } return new JobResult(new StreamableInternalSearchResult(result)); } catch (SearchError e){ throw e; } catch(Exception e){ throw new FastcatSearchException(e); } } @Override public void readFrom(DataInput input) throws IOException { this.queryMap = new QueryMap(); queryMap.readFrom(input); this.forMerging = input.readBoolean(); } @Override public void writeTo(DataOutput output) throws IOException { queryMap.writeTo(output); output.writeBoolean(forMerging); } }