This is an automated email from the git hooks/post-receive script. New commit to branch develop in repository coselmar. See http://git.codelutin.com/coselmar.git commit 06759735d46becf778abec041890efa344c8b6a1 Author: Yannick Martel <martel@©odelutin.com> Date: Fri Jan 2 17:33:20 2015 +0100 upgrade documation search by index to be able to search with several keywords --- .../indexation/DocumentsIndexationService.java | 53 ++++++++++++++++++++++ .../coselmar/services/v1/DocumentsWebService.java | 3 +- .../indexation/DocumentsIndexationServiceTest.java | 47 +++++++++++++++++++ 3 files changed, 101 insertions(+), 2 deletions(-) diff --git a/coselmar-rest/src/main/java/fr/ifremer/coselmar/services/indexation/DocumentsIndexationService.java b/coselmar-rest/src/main/java/fr/ifremer/coselmar/services/indexation/DocumentsIndexationService.java index 0c85c5b..0d1cb15 100644 --- a/coselmar-rest/src/main/java/fr/ifremer/coselmar/services/indexation/DocumentsIndexationService.java +++ b/coselmar-rest/src/main/java/fr/ifremer/coselmar/services/indexation/DocumentsIndexationService.java @@ -109,6 +109,59 @@ public class DocumentsIndexationService extends CoselmarSimpleServiceSupport { return documentIds; } + public List<String> searchDocuments(List<String> texts) throws IOException, ParseException { + DirectoryReader ireader = DirectoryReader.open(getLuceneUtils().getIndexWriter(), false); + IndexSearcher isearcher = new IndexSearcher(ireader); + + + BooleanQuery keywordsQuery = new BooleanQuery(); + + for (String text : texts) { + String[] words = text.split(" "); + + // Parse a simple query that searches for the "text": + BooleanQuery query = new BooleanQuery(); + + PhraseQuery nameQuery = new PhraseQuery(); + PhraseQuery summaryQuery = new PhraseQuery(); + PhraseQuery authorsQuery = new PhraseQuery(); + + for (String word : words) { + nameQuery.add(new Term(DOCUMENT_NAME_INDEX_PROPERTY, word.toLowerCase())); + summaryQuery.add(new Term(DOCUMENT_SUMMARY_INDEX_PROPERTY, word.toLowerCase())); + authorsQuery.add(new Term(DOCUMENT_AUTHORS_INDEX_PROPERTY, word.toLowerCase())); + } + + query.add(nameQuery, BooleanClause.Occur.SHOULD); + query.add(summaryQuery, BooleanClause.Occur.SHOULD); + query.add(authorsQuery, BooleanClause.Occur.SHOULD); + + query.add(new TermQuery(new Term(DOCUMENT_KEYWORD_INDEX_PROPERTY, text)), BooleanClause.Occur.SHOULD); + + + // Combine that with the type + //XXX ymartel : put to Occur.SHOULD to make an "OR" + keywordsQuery.add(query, BooleanClause.Occur.MUST); + } + + BooleanQuery fullQuery = new BooleanQuery(); + fullQuery.add(keywordsQuery, BooleanClause.Occur.MUST); + fullQuery.add(new TermQuery(new Term("type", DOCUMENT_TYPE)), BooleanClause.Occur.MUST); + + ScoreDoc[] hits = isearcher.search(fullQuery, null, 1000).scoreDocs; + + List<String> documentIds = new ArrayList(hits.length); + + for (ScoreDoc hit : hits) { + Document doc = isearcher.doc(hit.doc); + String documentId = doc.get(DOCUMENT_ID_INDEX_PROPERTY); + documentIds.add(documentId); + } + + ireader.close(); + return documentIds; + } + public void updateDocument(DocumentBean document) throws IOException { DirectoryReader ireader = DirectoryReader.open(getLuceneUtils().getIndexWriter(), false); IndexSearcher isearcher = new IndexSearcher(ireader); diff --git a/coselmar-rest/src/main/java/fr/ifremer/coselmar/services/v1/DocumentsWebService.java b/coselmar-rest/src/main/java/fr/ifremer/coselmar/services/v1/DocumentsWebService.java index c8f62ac..5ebda72 100644 --- a/coselmar-rest/src/main/java/fr/ifremer/coselmar/services/v1/DocumentsWebService.java +++ b/coselmar-rest/src/main/java/fr/ifremer/coselmar/services/v1/DocumentsWebService.java @@ -34,7 +34,6 @@ import java.util.Date; import java.util.List; import com.google.common.base.Function; -import com.google.common.base.Joiner; import com.google.common.base.Preconditions; import com.google.common.collect.Lists; import fr.ifremer.coselmar.beans.DocumentBean; @@ -125,7 +124,7 @@ public class DocumentsWebService extends CoselmarWebServiceSupport { DocumentsIndexationService documentsIndexationService = getServicesContext().newService(DocumentsIndexationService.class); try { - List<String> documentIds = documentsIndexationService.searchDocuments(Joiner.on(" ").join(searchKeywords)); + List<String> documentIds = documentsIndexationService.searchDocuments(searchKeywords); List<String> documentFullIds = getDocumentsFullId(documentIds); documentList = getDocumentDao().forTopiaIdIn(documentFullIds).findAll(); diff --git a/coselmar-rest/src/test/java/fr/ifremer/coselmar/services/indexation/DocumentsIndexationServiceTest.java b/coselmar-rest/src/test/java/fr/ifremer/coselmar/services/indexation/DocumentsIndexationServiceTest.java index 251c084..a7320a8 100644 --- a/coselmar-rest/src/test/java/fr/ifremer/coselmar/services/indexation/DocumentsIndexationServiceTest.java +++ b/coselmar-rest/src/test/java/fr/ifremer/coselmar/services/indexation/DocumentsIndexationServiceTest.java @@ -1,5 +1,6 @@ package fr.ifremer.coselmar.services.indexation; +import java.util.Arrays; import java.util.Date; import java.util.List; import java.util.Locale; @@ -166,6 +167,52 @@ public class DocumentsIndexationServiceTest extends AbstractCoselmarServiceTest } + @Test + public void testSearchDocumentWithKeywords() throws Exception { + CoselmarServicesContext serviceContext = getServiceContext(); + DocumentsIndexationService documentsIndexationService = + serviceContext.newService(DocumentsIndexationService.class); + + String documentOneId = "testSearchMultiple_document1"; + DocumentBean documentOne = new DocumentBean(documentOneId, + "Ceci n'est pas un document", "John Doe", Privacy.PUBLIC.name(), + new Date(), Lists.newArrayList("document", "test"), "testDocument", + "This is not a fake document used for test", "fr", null, "Jack, Jane", + null, null, false, null, "http://somewhere", "no comment"); + + documentsIndexationService.indexDocument(documentOne); + + + String documentTwoId = "testSearchMultiple_document2"; + DocumentBean documentTwo = new DocumentBean(documentTwoId, + "Tardis documentation", "The Doctor", Privacy.PUBLIC.name(), + new Date(), Lists.newArrayList("tardis", "documentation", "old", "new", "borrowed", "blue"), "testDocument", + "This is part of document about the TARDIS", "fr", null, "The Doctor, Rose, Amy, River, Clara", + null, null, false, null, "http://tardis.wikia.com/wiki/TARDIS", "no comment"); + documentsIndexationService.indexDocument(documentTwo); + + + List<String> documentMatchingDoctorIds = documentsIndexationService.searchDocuments(Arrays.asList("doctor")); + Assert.assertEquals(1, documentMatchingDoctorIds.size()); + Assert.assertEquals(documentTwoId, documentMatchingDoctorIds.get(0)); + + List<String> documentMatchingAmyAndDoctorIds = documentsIndexationService.searchDocuments(Arrays.asList("amy", "doctor")); + Assert.assertEquals(1, documentMatchingAmyAndDoctorIds.size()); + Assert.assertTrue(documentMatchingAmyAndDoctorIds.contains(documentTwoId)); + + List<String> documentMatchingAmyAndJackIds = documentsIndexationService.searchDocuments(Arrays.asList("amy", "jack")); + Assert.assertTrue(documentMatchingAmyAndJackIds.isEmpty()); + + List<String> documentMatchingAmyAndRoseIds = documentsIndexationService.searchDocuments(Arrays.asList("amy", "Sarah Jane")); + Assert.assertTrue(documentMatchingAmyAndRoseIds.isEmpty()); + + List<String> documentMatchingDocumentIds = documentsIndexationService.searchDocuments(Arrays.asList("document", "this is")); + Assert.assertEquals(2, documentMatchingDocumentIds.size()); + Assert.assertTrue(documentMatchingDocumentIds.contains(documentOneId)); + Assert.assertTrue(documentMatchingDocumentIds.contains(documentTwoId)); + + } + public void populate() throws Exception { CoselmarServicesContext serviceContext = getServiceContext(); DocumentsIndexationService documentsIndexationService = -- To stop receiving notification emails like this one, please contact codelutin.com SCM administrator <admin+scm@codelutin.com>.