2014-09-17 19 views
7

Dường như bất cứ khi nào tôi cập nhật tài liệu hiện có trong chỉ mục (cùng một hành vi để xóa/thêm), không thể tìm thấy tài liệu đó bằng một Truy vấn. Đây là đoạn mã ngắn:Lucene không thể tìm thấy tài liệu sau khi cập nhật

iw = newWinditerWriter (thư mục, cấu hình);

Document doc = new Document(); 
doc.add(new StringField("string", "a", Store.YES)); 
doc.add(new IntField("int", 1, Store.YES)); 

iw.addDocument(doc); 

Query query = new TermQuery(new Term("string","a")); 

Document[] hits = search(query); 
doc = hits[0]; 
print(doc); 

doc.removeField("int"); 
doc.add(new IntField("int", 2, Store.YES)); 

iw.updateDocument(new Term("string","a"), doc); 

hits = search(query); 
System.out.println(hits.length); 
System.out.println("_________________"); 

for(Document hit : search(new MatchAllDocsQuery())){ 
    print(hit); 
} 

này tạo ra giao diện điều khiển đầu ra sau đây:

stored,indexed,tokenized,omitNorms,indexOptions=DOCS_ONLY<string:a> 
stored<int:1> 
________________ 
0 
_________________ 
stored,indexed,tokenized,omitNorms,indexOptions=DOCS_ONLY<string:a> 
stored<int:2> 
________________ 

Dường như sau khi cập nhật, tài liệu (chứ không phải tài liệu mới) trong chỉ mục và được trả về bởi các MatchAllDocsQuery, nhưng không thể được tìm thấy bởi một TermQuery.

Full mẫu mã có sẵn tại http://pastebin.com/sP2Vav9v

Ngoài ra, điều này chỉ xảy ra (thứ hai tìm kiếm không làm việc) khi giá trị Stringfield chứa các ký tự đặc biệt (ví dụ file:/F: /).

+1

Bạn không thiếu 'iw.commit()'? – mindas

+0

Không thay đổi bất cứ điều gì. Cố gắng nó aleady. Ngoài ra, tìm kiếm sẽ mở ra một trình đọc mới từ người viết mỗi lần: DirectoryReader reader = DirectoryReader.open (iw, true); – Michael

+0

Tôi dường như đang gặp vấn đề tương tự. Lucene là phiên bản nào? – carlspring

Trả lời

4

Mã mà bạn đã tham chiếu bằng pastebin không tìm thấy bất kỳ thứ gì vì StringField của bạn không là gì ngoài một từ dừng (a). Thay thế a bằng thứ gì đó không phải là từ dừng (ví dụ: ax) làm cho cả hai tìm kiếm trả về 1 tài liệu.

Bạn cũng sẽ đạt được kết quả chính xác nếu bạn xây dựng StandardAnalyzer bằng bộ từ dừng trống (CharArraySet.EMPTY_SET) nhưng vẫn đang sử dụng a cho StringField. Điều này sẽ không hoạt động cho file:/F:/.

Tuy nhiên, giải pháp tốt nhất là trường hợp này là thay thế StandardAnalyzer bằng KeywordAnalyzer.

+0

Tôi nghĩ StringField không được phân tích? Ngoài ra, cách cập nhật có tác dụng này, nhưng việc chèn một tài liệu mới thì không? – Michael

+0

'StringField' không được phân tích, điều đó đúng. Nhưng bộ lọc từ dừng vẫn được áp dụng - xem 'StandardAnalyzer' Javadoc. Cuốn sách Lucene in Action (trang 120-121) nói: "' StandardAnalyzer' cũng bao gồm việc loại bỏ từ dừng ". Về việc cập nhật/chèn câu hỏi - Tôi không hoàn toàn chắc chắn. Tôi sẽ cố gắng để gỡ lỗi và đăng kết quả nếu tôi tìm thấy bất kỳ. – mindas

1

Tôi có thể loại bỏ điều này bằng cách tạo lại thư mục làm việc của mình sau khi tất cả các thao tác lập chỉ mục: tạo một thư mục mới chỉ cho các hoạt động lập chỉ mục này có tên "path_dir". Nếu bạn đã cập nhật, hãy gọi các thao tác sau và thực hiện lại tất cả các tác phẩm trước đó của bạn.

StandardAnalyzer analyzer = new StandardAnalyzer(Version.LUCENE_46); 
FSDirectory dir; 
try { 
    // delete indexing files : 
    dir = FSDirectory.open(new File(path_dir)); 
    IndexWriterConfig config = new IndexWriterConfig(Version.LUCENE_46, analyzer); 
    IndexWriter writer = new IndexWriter(dir, config); 
    writer.deleteAll(); 
    writer.close(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 

Tuy nhiên, lưu ý rằng cách này sẽ rất chậm nếu bạn đang xử lý dữ liệu lớn.

+0

Đây chính xác là "bản sửa lỗi"? Xóa chỉ mục hoàn toàn vô lý! Điều gì sẽ xảy ra nếu bạn cần cập nhật 10 000 000 bản ghi năm lần và bạn phải xóa chỉ mục mỗi lần ?! Không thể chấp nhận được. – carlspring

+0

Tôi đã nhận xét về dữ liệu lớn ở phần cuối của câu trả lời. Tôi có thể làm cho mã của tôi hoạt động tốt theo cách này. Vì tôi không xử lý dữ liệu lớn, nó không phải là vấn đề đối với tôi. Nếu michael cũng có dữ liệu nhỏ, nó có thể hoạt động. – balik

Các vấn đề liên quan