ZEPPELIN-501: fix + test for bug in index key structure

This commit is contained in:
Alexander Bezzubov 2015-12-23 17:06:23 +09:00
parent 78f69a3ae9
commit c77d53b8b0
2 changed files with 48 additions and 19 deletions

View file

@ -61,14 +61,16 @@ import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
/**
* Service for search (both, indexing and query) the notebooks
* Service for search (both, indexing and query) the notebooks.
*
* TODO(bzz): document thread-safety
* Query is thread-safe, as creates new IndexReader every time.
* Index is thread-safe, as re-uses single IndexWriter, which is thread-safe.
*/
public class SearchService {
private static final Logger LOG = LoggerFactory.getLogger(SearchService.class);
static final String SEARCH_FIELD = "contents";
private static final String SEARCH_FIELD = "contents";
static final String PARAGRAPH = "paragraph";
static final String ID_FIELD = "id";
Directory ramDirectory;
@ -224,7 +226,7 @@ public class SearchService {
static String formatId(String noteId, Paragraph p) {
String id = noteId;
if (null != p) {
id = Joiner.on('/').join(id, "paragraphs", p.getId());
id = Joiner.on('/').join(id, PARAGRAPH, p.getId());
}
return id;
}
@ -232,7 +234,7 @@ public class SearchService {
static String formatDeleteId(String noteId, Paragraph p) {
String id = noteId;
if (null != p) {
id = Joiner.on('/').join(id, "paragraphs", p.getId());
id = Joiner.on('/').join(id, PARAGRAPH, p.getId());
} else {
id = id + "*";
}
@ -275,7 +277,7 @@ public class SearchService {
long start = System.nanoTime();
try {
for (Note note : collection) {
addIndexDoc(note);
addIndexDocAsync(note);
docsIndexed++;
}
} catch (IOException e) {
@ -293,11 +295,26 @@ public class SearchService {
}
/**
* Indexes the given notebook
* Indexes the given notebook.
*
* @throws IOException If there is a low-level I/O error
*/
public void addIndexDoc(Note note) throws IOException {
public void addIndexDoc(Note note) {
try {
addIndexDocAsync(note);
writer.commit();
} catch (IOException e) {
LOG.error("Failed to add note {} to index", note, e);
}
}
/**
* Indexes the given notebook, but does not commit changes.
*
* @param note
* @throws IOException
*/
private void addIndexDocAsync(Note note) throws IOException {
indexNoteName(writer, note.getId(), note.getName());
for (Paragraph doc : note.getParagraphs()) {
if (doc.getText() == null) {
@ -315,6 +332,17 @@ public class SearchService {
deleteDoc(note, null);
}
/**
* Deletes doc for a given
*
* @param note
* @param p
* @throws IOException
*/
public void deleteIndexDoc(Note note, Paragraph p) {
deleteDoc(note, p);
}
private void deleteDoc(Note note, Paragraph p) {
if (null == note) {
LOG.error("Trying to delete note by reference to NULL");
@ -331,17 +359,6 @@ public class SearchService {
LOG.debug("Done, index contains {} docs now" + writer.numDocs());
}
/**
* Deletes doc for a given
*
* @param note
* @param p
* @throws IOException
*/
public void deleteIndexDoc(Note note, Paragraph p) {
deleteDoc(note, p);
}
/**
* Frees the recourses used by Lucene index
*/

View file

@ -35,6 +35,7 @@ import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableList;
public class SearchServiceTest {
@ -103,6 +104,17 @@ public class SearchServiceTest {
assertThat(results.get(0)).containsEntry("id", note1.getId());
}
@Test public void indexKeyContract() throws IOException {
//give
Note note1 = newNoteWithParapgraph("Notebook1", "test");
//when
notebookIndex.addIndexDoc(note1);
//then
String id = resultForQuery("test").get(0).get(SearchService.ID_FIELD);
assertThat(Splitter.on("/").split(id)) //key structure <noteId>/paragraph/<paragraphId>
.containsAllOf(note1.getId(), SearchService.PARAGRAPH, note1.getLastParagraph().getId());
}
@Test //(expected=IllegalStateException.class)
public void canNotSearchBeforeIndexing() {