Lucene의 사용자 지정 점수

3653 단어
Lucene을 사용하여 질의하는 경우 기본적으로 평점 기준으로 높음부터 낮음까지 정렬됩니다.
여기 평점은 어디서 났을까요?원래 루틴 자체가 키워드가 나오는 빈도 등에 따라 하나의 평점을 계산하는데, 이를 원시 평점이라고 부른다.
이 원시적인 평점은 왕왕 우리의 실제 수요를 만족시킬 수 없다.채점 규칙을 사용자 정의해야 합니다.
Lucene은 원래 Query 객체를 org와 함께 사용할 수 있습니다.apache.lucene.search.function.FieldScoreQuery 객체는 org에 매개 변수로 전달됩니다.apache.lucene.search.function 패키지의 CustomScoreQuery 클래스의 구조 함수로 CustomScoreQuery의 대상을 얻어냅니다.
	public void searchByScoreQuery() {
		try {
			IndexSearcher searcher = new IndexSearcher(IndexReader.open(FileIndexUtils.getDirectory()));
			Query q = new TermQuery(new Term("content","java"));
			// 
			FieldScoreQuery fd = new FieldScoreQuery("score",Type.INT);
			// , 
			MyCustomScoreQuery query = new MyCustomScoreQuery(q,fd);
			TopDocs tds = null;
			tds = searcher.search(query, 100);
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
			for(ScoreDoc sd:tds.scoreDocs) {
				Document d = searcher.doc(sd.doc);
				System.out.println(sd.doc+":("+sd.score+")" +
						"["+d.get("filename")+"��"+d.get("path")+"��--->"+
						d.get("size")+"-----"+sdf.format(new Date(Long.valueOf(d.get("date"))))+"]");
			}
			searcher.close();
		} catch (CorruptIndexException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

그럼 루틴에서는 어떻게 자신의 채점 규칙을 작성합니까?
1. 클래스 MyCustomScoreQuery 계승CustomScoreQuery를 만들고 getCustomScoreProvider 방법을 덮어씁니다.
 
	@SuppressWarnings("serial")
	private class MyCustomScoreQuery extends CustomScoreQuery {
		
		public MyCustomScoreQuery(Query subQuery, ValueSourceQuery valSrcQuery) {
			super(subQuery, valSrcQuery);
		}
		
		@Override
		protected CustomScoreProvider getCustomScoreProvider(IndexReader reader)
				throws IOException {
			// * 
			// , 
			/**
			 *  
			 *  CustomScoreProvider
			 *  customScore 
			 */
			return new MyCustomScoreProvider(reader);
		}
		
	}

2. 클래스 MyCustomScoreProvider를 만들고 CustomScoreProvider를 계승하여customScore 방법을 덮어씁니다.
이 두 단계의 연관성은 MyCustomScoreProvider를 MyCustomScoreQuery 클래스의 getcustomScoreProvider 방법의 반환값으로 삼는 것이다.
	private class MyCustomScoreProvider extends CustomScoreProvider {

		public MyCustomScoreProvider(IndexReader reader) {
			super(reader);
		}
		
		/**
		 * subQueryScore  
		 * valSrcScore  
		 */
		@Override
		public float customScore(int doc, float subQueryScore, float valSrcScore)
				throws IOException {
			return subQueryScore/valSrcScore;
		}
		
	}

자신의 채점 규칙은 MyCustomScoreProvider 클래스의customScore 방법 체내에서 정의됩니다.문서에 있는 필드의 값을 사용해야 한다면, 필드 캐시로 가져올 수 있습니다.FieldCache.DEFAULT.getStrings
	private class FilenameScoreProvider extends CustomScoreProvider {
		String[] filenames = null;
		public FilenameScoreProvider(IndexReader reader) {
			super(reader);
			try {
				filenames = FieldCache.DEFAULT.getStrings(reader, "filename");
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
		@Override
		public float customScore(int doc, float subQueryScore, float valSrcScore)
				throws IOException {
			// doc field 
			/*
			 *  reader , , 
			 * filenames = FieldCache.DEFAULT.getStrings(reader, "filename"); fieldname 
			 */
			String filename = filenames[doc];
			if(filename.endsWith(".txt")||filename.endsWith(".ini")) {
				return subQueryScore*1.5f;
			}
			return subQueryScore/1.5f;
		}
	}

 
 
 
 
 
 
 
 

좋은 웹페이지 즐겨찾기