이 작은 프로그램을 작성하기 위해 lucene 쿼리 구문이 어떻게 작동하는지 이해하려고합니다. NumericRangeQuery를 사용할 때 원하는 문서를 찾을 수 있지만 검색 조건을 파싱하려고 할 때 동일한 조건을 사용하지만 히트를 찾을 수 없습니다. 차이점은 분석기로 설명 할 수 있지만 숫자 값은 제거하지 않는 StandardAnalyzer가 사용된다는 것을 알고 있습니다.숫자 필드를 사용하는 Lucene 쿼리가 아무 것도 찾지 못했습니다.
누군가 내가 뭘 잘못하고 있다고 말할 수 있습니까? 감사합니다. .
package org.burre.lucene.matching;
import java.io.IOException;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.*;
import org.apache.lucene.index.*;
import org.apache.lucene.queryparser.classic.ParseException;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.NumericRangeQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.store.*;
import org.apache.lucene.util.Version;
public class SmallestEngine {
private static final Version VERSION=Version.LUCENE_48;
private StandardAnalyzer analyzer = new StandardAnalyzer(VERSION);
private Directory index = new RAMDirectory();
private Document buildDoc(String name, int beds) {
Document doc = new Document();
doc.add(new StringField("name", name, Field.Store.YES));
doc.add(new IntField("beds", beds, Field.Store.YES));
return doc;
}
public void buildSearchEngine() throws IOException {
IndexWriterConfig config = new IndexWriterConfig(VERSION,
analyzer);
IndexWriter w = new IndexWriter(index, config);
// Generate 10 houses with 0 to 3 beds
for (int i=0;i<10;i++)
w.addDocument(buildDoc("house"+(100+i),i % 4));
w.close();
}
/**
* Execute the query and show the result
*/
public void search(Query q) throws IOException {
System.out.println("executing query\""+q+"\"");
IndexReader reader = DirectoryReader.open(index);
try {
IndexSearcher searcher = new IndexSearcher(reader);
ScoreDoc[] hits = searcher.search(q, 10).scoreDocs;
System.out.println("Found " + hits.length + " hits.");
for (int i = 0; i < hits.length; ++i) {
int docId = hits[i].doc;
Document d = searcher.doc(docId);
System.out.println(""+(i+1)+". " + d.get("name") + ", beds:"
+ d.get("beds"));
}
} finally {
if (reader != null)
reader.close();
}
}
public static void main(String[] args) throws IOException, ParseException {
SmallestEngine me = new SmallestEngine();
me.buildSearchEngine();
System.out.println("SearchByRange");
me.search(NumericRangeQuery.newIntRange("beds", 3, 3,true,true));
System.out.println("-----------------");
System.out.println("SearchName");
me.search(new QueryParser(VERSION,"name",me.analyzer).parse("house107"));
System.out.println("-----------------");
System.out.println("Search3Beds");
me.search(new QueryParser(VERSION,"beds",me.analyzer).parse("3"));
System.out.println("-----------------");
System.out.println("Search3BedsInRange");
me.search(new QueryParser(VERSION,"name",me.analyzer).parse("beds:[3 TO 3]"));
}
}
이 프로그램의 출력은 다음과 같습니다
SearchByRange
executing query"beds:[3 TO 3]"
Found 2 hits.
1. house103, beds:3
2. house107, beds:3
-----------------
SearchName
executing query"name:house107"
Found 1 hits.
1. house107, beds:3
-----------------
Search3Beds
executing query"beds:3"
Found 0 hits.
-----------------
Search3BedsInRange
executing query"beds:[3 TO 3]"
Found 0 hits.
Lucene이 숫자 조건을 해석 할 수는 없지만 실망감은 조금 있습니다. 귀하의 솔루션이 도움이되었습니다. 내 구현은 모든 숫자 필드 (침대뿐만 아니라)에 대해서만 작동합니다. { return NumericRangeQuery.newIntRange (field, part2), part1 포함, part2 포함); } – Conffusion
Lucene에서 마법을 기대합니다. Lucene은 독립형 제품이 아니라 라이브러리입니다. 원하는 기능은 Solr 또는 Elasticsearch에 적합합니다. 어쨌든,이 클래스가하는 일은 "필드 이름이 X이면 숫자 쿼리를 구성하는 것"입니다. 게다가, 그것은 당신이'QueryParser' 메카니즘에 완벽하게 연결될 수 있도록 해줍니다 : 당신은 필드 이름을 제공 할 필요가 있고 쿼리를 직접 파싱 할 필요가 없습니다. 나는 그렇게 많이 생각하지 않는다. – mindas
p.s. 대답을 원한다면 [동의] (http://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work)를 원할 수 있습니다. 이것이이 사이트의 작동 방식입니다. 고맙습니다! – mindas