📄 dbsearchindexer.java
字号:
}
}
/**
* Indexing thread logic. It wakes up once a minute to see if any threaded
* action should take place.
*/
public void run() {
while (true){
//If auto indexing is on
if (autoIndex) {
long now = System.currentTimeMillis();
//If we want to re-index everything.
if (lastIndexed == 0) {
synchronized(indexLock) {
rebuildIndex(now);
lastIndexed = now;
//Save the time as a Yazd property.
PropertyManager.setProperty("DbSearchIndexer.lastIndexed",
"" + lastIndexed);
}
}
//We only want to do an update.
else {
long nextIndex = lastIndexed + updateInterval;
if (now > nextIndex) {
synchronized(indexLock) {
updateIndex(lastIndexed, now);
lastIndexed = now;
//Save the time as a Yazd property.
PropertyManager.setProperty("DbSearchIndexer.lastIndexed",
"" + lastIndexed);
}
}
}
}
//sleep for 1 minute and then check again.
try {
this.sleep(60000);
}
catch (Exception e) {
e.printStackTrace();
}
}
}
/**
* Indexes an indivual message. The connection is assumed to be open when
* passed in and will remain open after the method is done executing.
*/
protected final void addMessageToIndex(IndexWriter writer, int messageID,
String subject, String body, int userID, int threadID, int forumID,
java.util.Date creationDate) throws IOException
{
if (writer == null) {
return;
}
//Ignore messages with a null subject or body.
if (subject == null || body == null) {
return;
}
Document doc = new Document();
doc.add(Field.Keyword("messageID", Integer.toString(messageID)));
doc.add(new Field("userID", Integer.toString(userID), false, true, false));
doc.add(new Field("threadID", Integer.toString(threadID), false, true, false));
doc.add(new Field("forumID", Integer.toString(forumID), false, true, false));
doc.add(Field.UnStored("subject", subject));
doc.add(Field.UnStored("body", body));
doc.add(new Field("creationDate", DateField.dateToString(creationDate), false, true, false));
writer.addDocument(doc);
}
/**
* Deletes a message from the index.
*/
protected final void deleteMessagesFromIndex(int [] messages) throws IOException {
if (messages == null) {
return;
}
IndexReader reader = getReader();
if (reader == null) {
//Reader will be null if the search index doesn't exist.
return;
}
Term messageIDTerm;
for (int i=0; i<messages.length; i++) {
messageIDTerm = new Term("messageID", Integer.toString(messages[i]));
try {
reader.delete(messageIDTerm);
}
catch (Exception e) { }
}
try {
reader.close();
}
catch (Exception e) { }
}
/**
* Rebuilds the search index from scratch. It deletes the entire index
* and word tables and then indexes every message up to the end time.
*/
protected final void rebuildIndex(long end) {
System.err.println("Rebuilding index...");
IndexWriter writer = null;
Connection con = null;
try {
writer = getWriter(true);
con = DbConnectionManager.getConnection();
PreparedStatement pstmt = con.prepareStatement(MESSAGES_BEFORE_DATE);
pstmt.setString(1, Long.toString(end));
ResultSet rs = pstmt.executeQuery();
while (rs.next()) {
int messageID = rs.getInt(1);
int userID = rs.getInt(2);
int threadID = rs.getInt(3);
int forumID = rs.getInt(4);
String subject = rs.getString(5);
String body = rs.getString(6);
java.util.Date creationDate =
new java.util.Date(Long.parseLong(rs.getString(7).trim()));
//ForumMessage message = new DbForumMessage(messageID, factory);// factory.getMessage(messageID);
addMessageToIndex(writer, messageID, subject, body, userID, threadID, forumID, creationDate);
}
pstmt.close();
}
catch( Exception sqle ) {
sqle.printStackTrace();
}
finally {
try { con.close(); }
catch (Exception e) { e.printStackTrace(); }
try {
//A rebuild of the index warrants calling optimize.
writer.optimize();
}
catch (Exception e) { }
try {
writer.close();
}
catch (Exception e) {
e.printStackTrace();
}
}
System.err.println("Done rebuilding index.");
}
/**
* Updates the index. It first deletes any messages in the index between
* the start and end times, and then adds all messages to the index that
* are between the start and end times.
*/
protected final void updateIndex(long start, long end) {
Connection con = null;
PreparedStatement pstmt = null;
IndexWriter writer = null;
int [] messages = null;
try {
con = DbConnectionManager.getConnection();
//For a clean update, we need to make sure that we first delete
//any index entries that were made since we last updated. This
//might happen if a process was calling indexMessage() between runs
//of this method. For this reason, the two types of indexing (manual
//and automatic) should not be intermixed. However, we still perform
//this deletion to be safe.
pstmt = con.prepareStatement(MESSAGES_SINCE_DATE_COUNT);
pstmt.setString(1, Long.toString(start));
pstmt.setString(2, Long.toString(end));
ResultSet rs = pstmt.executeQuery();
rs.next();
int messageCount = rs.getInt(1);
messages = new int[messageCount];
pstmt.close();
pstmt = con.prepareStatement(MESSAGES_SINCE_DATE);
pstmt.setString(1, Long.toString(start));
pstmt.setString(2, Long.toString(end));
rs = pstmt.executeQuery();
for (int i=0; i<messages.length; i++) {
rs.next();
messages[i] = rs.getInt("messageID");
}
}
catch (Exception e) {
e.printStackTrace();
}
finally {
try { pstmt.close(); }
catch (Exception e) { e.printStackTrace(); }
try { con.close(); }
catch (Exception e) { e.printStackTrace(); }
}
try {
deleteMessagesFromIndex(messages);
//Finally, index all new messages;
writer = getWriter(false);
for (int i=0; i<messages.length; i++) {
ForumMessage message = factory.getMessage(messages[i]);
addMessageToIndex(writer, message.getID(),
message.getUnfilteredSubject(), message.getUnfilteredBody(),
message.getUser().getID(), message.getForumThread().getID(),
message.getForumThread().getForum().getID(),
message.getCreationDate()
);
}
}
catch( Exception e ) {
e.printStackTrace();
}
finally {
try { writer.close(); }
catch (Exception e) { e.printStackTrace(); }
}
}
/**
* Returns a Lucene IndexWriter.
*/
private static IndexWriter getWriter(boolean create) throws IOException {
if (indexPath == null) {
//Get path of where search index should be. It should be
//the search subdirectory of [yazdHome].
String yazdHome = PropertyManager.getProperty("yazdHome");
if (yazdHome == null) {
System.err.println("ERROR: the yazdHome property is not set.");
throw new IOException("Unable to open index for searching " +
"because yazdHome was not set.");
}
indexPath = yazdHome + File.separator + "search";
}
IndexWriter writer = null;
//If create is true, we always want to create a new index writer.
if (create) {
try {
writer = new IndexWriter(indexPath, analyzer, true);
}
catch (Exception e) {
System.err.println("ERROR: Failed to create a new index writer.");
e.printStackTrace();
}
}
//Otherwise, use an existing index if it exists.
else {
if (indexExists(indexPath)) {
try {
writer = new IndexWriter(indexPath, analyzer, false);
}
catch (Exception e) {
System.err.println("ERROR: Failed to open an index writer.");
e.printStackTrace();
}
}
else {
try {
writer = new IndexWriter(indexPath, analyzer, true);
}
catch (Exception e) {
System.err.println("ERROR: Failed to create a new index writer.");
e.printStackTrace();
}
}
}
return writer;
}
/**
* Returns a Lucene IndexReader.
*/
private static IndexReader getReader() throws IOException {
if (indexPath == null) {
//Get path of where search index should be. It should be
//the search subdirectory of [yazdHome].
String yazdHome = PropertyManager.getProperty("yazdHome");
if (yazdHome == null) {
System.err.println("ERROR: the yazdHome property is not set.");
throw new IOException("Unable to open index for searching " +
"because yazdHome was not set.");
}
indexPath = yazdHome + File.separator + "search";
}
if (indexExists(indexPath)) {
IndexReader reader = IndexReader.open(indexPath);
return reader;
}
else {
return null;
}
}
/**
* Returns true if the search index exists at the specified path.
*
* @param indexPath the path to check for the search index at.
*/
private static boolean indexExists(String indexPath) {
//Lucene always creates a file called "segments" -- if it exists, we
//assume that the search index exists.
File segments = new File(indexPath + File.separator + "segments");
return segments.exists();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -