나는 Lucene의 관계형 데이터를 저장하는 데 많은 어려움을 겪었지만, 당신이 가지고있는 것은 쉽게 고쳐야한다.
그룹 필드를 토큰으로 바꾸면 필드 값에서 하위 문자열을 검색 할 수 있습니다. 필드를 untokenized로 추가하면 예상대로 작동합니다.
는 다음의 짧은 코드를 확인하십시오 :
internal class Program {
private static void Main(string[] args) {
var directory = new RAMDirectory();
var writer = new IndexWriter(directory, new StandardAnalyzer());
AddDocument(writer, "group", "stuff", Field.Index.UN_TOKENIZED);
AddDocument(writer, "group", "other stuff", Field.Index.UN_TOKENIZED);
writer.Close(true);
var searcher = new IndexSearcher(directory);
Hits hits = searcher.Search(new TermQuery(new Term("group", "stuff")));
for (int i = 0; i < hits.Length(); i++) {
Console.WriteLine(hits.Doc(i).GetField("group").StringValue());
}
}
private static void AddDocument(IndexWriter writer, string name, string value, Field.Index index) {
var document = new Document();
document.Add(new Field(name, value, Field.Store.YES, index));
writer.AddDocument(document);
}
}
샘플은 untokenized있는 인덱스에 두 개의 문서를 추가는, 물건에 대한 검색을 수행하고 하나 개의 히트를 가져옵니다. 토큰 화 된 코드를 추가하도록 코드를 변경했다면 지금 보았던 것과 같이 두 번의 히트가 있습니다.
관계형 데이터에 Lucene을 사용할 때의 문제점은 와일드 카드 및 범위 검색이 항상 작동 할 것으로 예상된다는 것입니다. Lucene이 이러한 쿼리를 해결하는 방식 때문에 인덱스가 클 경우 실제로 그렇지 않습니다. 답장을
private static void Main(string[] args) {
var directory = new RAMDirectory();
var writer = new IndexWriter(directory, new StandardAnalyzer());
var documentA = new Document();
documentA.Add(new Field("name", "A", Field.Store.YES, Field.Index.UN_TOKENIZED));
documentA.Add(new Field("group", "stuff", Field.Store.YES, Field.Index.UN_TOKENIZED));
documentA.Add(new Field("group", "other stuff", Field.Store.YES, Field.Index.UN_TOKENIZED));
writer.AddDocument(documentA);
var documentB = new Document();
documentB.Add(new Field("name", "B", Field.Store.YES, Field.Index.UN_TOKENIZED));
documentB.Add(new Field("group", "stuff", Field.Store.YES, Field.Index.UN_TOKENIZED));
writer.AddDocument(documentB);
var documentC = new Document();
documentC.Add(new Field("name", "C", Field.Store.YES, Field.Index.UN_TOKENIZED));
documentC.Add(new Field("group", "other stuff", Field.Store.YES, Field.Index.UN_TOKENIZED));
writer.AddDocument(documentC);
writer.Close(true);
var query1 = new TermQuery(new Term("group", "stuff"));
SearchAndDisplay("First sample", directory, query1);
var query2 = new TermQuery(new Term("group", "other stuff"));
SearchAndDisplay("Second sample", directory, query2);
var query3 = new BooleanQuery();
query3.Add(new TermQuery(new Term("group", "stuff")), BooleanClause.Occur.MUST);
query3.Add(new TermQuery(new Term("group", "other stuff")), BooleanClause.Occur.MUST);
SearchAndDisplay("Third sample", directory, query3);
}
private static void SearchAndDisplay(string title, Directory directory, Query query3) {
var searcher = new IndexSearcher(directory);
Hits hits = searcher.Search(query3);
Console.WriteLine(title);
for (int i = 0; i < hits.Length(); i++) {
Console.WriteLine(hits.Doc(i).GetField("name").StringValue());
}
}
안녕 HakonB, 감사 :
또 다른 샘플
는 동작을 설명한다. 나는 몇 가지 다른 조회를 위해 untokenized를 사용했지만 문제는 하나의 항목이 "Stuff"및 "Other Stuff"에있을 수 있으며 하나 또는 둘 모두를 검색 할 때 발견되어야합니다. EG : 단지 물건 물건을 단지 다른 물건 검색 C {A, B} 다른 것들에 대한 검색 {A, C} 물건과 다른 물건 {에 대한 검색 물건과 다른 물건 B에서 A} – fyjham올바른 결과를 얻는 방법을 보여주는 또 다른 샘플을 추가했습니다. - 지금 이해하면 되겠습니다. – HakonB
아, 고마워! 그게 정확히 내가 한 것 같아. 실제로 하나의 문서에 동일한 이름의 2 개의 필드를 추가 할 수는 없었습니다. 아직도 내가 생각하는 전형적인 관계형 데이터베이스와 너무 흡사하다.) – fyjham