Example usage for org.apache.lucene.index IndexWriter addDocument

List of usage examples for org.apache.lucene.index IndexWriter addDocument

Introduction

In this page you can find the example usage for org.apache.lucene.index IndexWriter addDocument.

Prototype

public long addDocument(Iterable<? extends IndexableField> doc) throws IOException 

Source Link

Document

Adds a document to this index.

Usage

From source file:com.codenvy.test.lucene.IndexFiles.java

License:Open Source License

/** Indexes a single document */
static void indexDoc(IndexWriter writer, Path file, long lastModified) throws IOException {
    try (InputStream stream = Files.newInputStream(file)) {
        // make a new, empty document
        Document doc = new Document();

        // Add the path of the file as a field named "path".  Use a
        // field that is indexed (i.e. searchable), but don't tokenize
        // the field into separate words and don't index term frequency
        // or positional information:
        Field pathField = new StringField("path", file.toString(), Field.Store.YES);
        doc.add(pathField);/* ww  w . j  a  v  a2s.  co  m*/

        // Add the last modified date of the file a field named "modified".
        // Use a LongField that is indexed (i.e. efficiently filterable with
        // NumericRangeFilter).  This indexes to milli-second resolution, which
        // is often too fine.  You could instead create a number based on
        // year/month/day/hour/minutes/seconds, down the resolution you require.
        // For example the long value 2011021714 would mean
        // February 17, 2011, 2-3 PM.
        doc.add(new LongField("modified", lastModified, Field.Store.NO));

        // Add the contents of the file to a field named "contents".  Specify a Reader,
        // so that the text of the file is tokenized and indexed, but not stored.
        // Note that FileReader expects the file to be in UTF-8 encoding.
        // If that's not the case searching for special characters will fail.
        doc.add(new TextField("contents",
                new BufferedReader(new InputStreamReader(stream, StandardCharsets.UTF_8))));

        if (writer.getConfig().getOpenMode() == OpenMode.CREATE) {
            // New index, so we just add the document (no old document can be there):
            System.out.println("adding " + file);
            writer.addDocument(doc);
        } else {
            // Existing index (an old copy of this document may have been indexed) so
            // we use updateDocument instead to replace the old one matching the exact
            // path, if present:
            System.out.println("updating " + file);
            writer.updateDocument(new Term("path", file.toString()), doc);
        }
    }
}

From source file:com.common.search.IKAnalyzerDemo.java

License:Apache License

public static void main(String[] args) {
    // Lucene Document
    String fieldName = "text";
    // /* w  ww .  j  a  v  a2s . c o m*/
    String text = "IK Analyzer ";
    // IKAnalyzer
    Analyzer analyzer = new IKAnalyzer();
    Directory directory = null;
    IndexWriter iwriter = null;
    IndexReader ireader = null;
    IndexSearcher isearcher = null;
    try {
        // 
        directory = new RAMDirectory();
        // IndexWriterConfig
        IndexWriterConfig iwConfig = new IndexWriterConfig(Version.LUCENE_34, analyzer);
        iwConfig.setOpenMode(OpenMode.CREATE_OR_APPEND);
        iwriter = new IndexWriter(directory, iwConfig);
        // 
        Document doc = new Document();
        doc.add(new Field("ID", "10000", Field.Store.YES, Field.Index.NOT_ANALYZED));
        doc.add(new Field(fieldName, text, Field.Store.YES, Field.Index.ANALYZED));
        iwriter.addDocument(doc);
        iwriter.close();
        // **********************************
        // 
        ireader = IndexReader.open(directory);
        isearcher = new IndexSearcher(ireader);
        String keyword = "";
        // QueryParserQuery
        QueryParser qp = new QueryParser(Version.LUCENE_34, fieldName, analyzer);
        qp.setDefaultOperator(QueryParser.AND_OPERATOR);
        Query query = qp.parse(keyword);
        // 5
        TopDocs topDocs = isearcher.search(query, 5);
        System.out.println(" " + topDocs.totalHits);
        // 
        ScoreDoc[] scoreDocs = topDocs.scoreDocs;
        for (int i = 0; i < topDocs.totalHits; i++) {
            Document targetDoc = isearcher.doc(scoreDocs[i].doc);
            System.out.println(" " + targetDoc.toString());
        }
    } catch (CorruptIndexException e) {
        e.printStackTrace();
    } catch (LockObtainFailedException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } catch (ParseException e) {
        e.printStackTrace();
    } finally {
        if (ireader != null) {
            try {
                ireader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if (directory != null) {
            try {
                directory.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

From source file:com.company.Indexer.java

License:Apache License

/** Indexes a single document */
static void indexDoc(IndexWriter writer, Path file, long lastModified) throws IOException {
    try (InputStream stream = Files.newInputStream(file)) {
        // make a new, empty document

        JTidyHTMLHandler mrT = new JTidyHTMLHandler();

        Document doc = mrT.getDocument(stream);

        // Add the path of the file as a field named "path".  Use a
        // field that is indexed (i.e. searchable), but don't tokenize
        // the field into separate words and don't index term frequency
        // or positional information:
        Field pathField = new StringField("path", file.toString(), Field.Store.YES);
        doc.add(pathField);/*  w w  w . ja v a 2 s.co m*/

        // Add the last modified date of the file a field named "modified".
        // Use a LongField that is indexed (i.e. efficiently filterable with
        // NumericRangeFilter).  This indexes to milli-second resolution, which
        // is often too fine.  You could instead create a number based on
        // year/month/day/hour/minutes/seconds, down the resolution you require.
        // For example the long value 2011021714 would mean
        // February 17, 2011, 2-3 PM.
        doc.add(new LongField("modified", lastModified, Field.Store.NO));

        // Add the contents of the file to a field named "contents".  Specify a Reader,
        // so that the text of the file is tokenized and indexed, but not stored.
        // Note that FileReader expects the file to be in UTF-8 encoding.
        // If that's not the case searching for special characters will fail.

        //doc.add(new TextField("contents", new BufferedReader(new InputStreamReader(stream, StandardCharsets.UTF_8))));

        if (writer.getConfig().getOpenMode() == IndexWriterConfig.OpenMode.CREATE) {
            // New index, so we just add the document (no old document can be there):
            System.out.println("adding " + file);
            writer.addDocument(doc);
        } else {
            // Existing index (an old copy of this document may have been indexed) so
            // we use updateDocument instead to replace the old one matching the exact
            // path, if present:
            System.out.println("updating " + file);
            writer.updateDocument(new Term("path", file.toString()), doc);
        }
    }
}

From source file:com.company.IndexFiles.java

License:Apache License

/** Indexes a single document */
static void indexDoc(IndexWriter writer, Path file, long lastModified) throws IOException {
    try (InputStream stream = Files.newInputStream(file)) {
        // make a new, empty document
        Document doc = new Document();

        // Add the path of the file as a field named "path".  Use a
        // field that is indexed (i.e. searchable), but don't tokenize
        // the field into separate words and don't index term frequency
        // or positional information:
        Field pathField = new StringField("path", file.toString(), Field.Store.YES);
        doc.add(pathField);/*from  ww  w.  ja  v  a 2s  .c  om*/

        // Add the last modified date of the file a field named "modified".
        // Use a LongField that is indexed (i.e. efficiently filterable with
        // NumericRangeFilter).  This indexes to milli-second resolution, which
        // is often too fine.  You could instead create a number based on
        // year/month/day/hour/minutes/seconds, down the resolution you require.
        // For example the long value 2011021714 would mean
        // February 17, 2011, 2-3 PM.
        doc.add(new LongField("modified", lastModified, Field.Store.NO));

        // Add the contents of the file to a field named "contents".  Specify a Reader,
        // so that the text of the file is tokenized and indexed, but not stored.
        // Note that FileReader expects the file to be in UTF-8 encoding.
        // If that's not the case searching for special characters will fail.
        doc.add(new TextField("contents",
                new BufferedReader(new InputStreamReader(stream, StandardCharsets.UTF_8))));

        if (writer.getConfig().getOpenMode() == IndexWriterConfig.OpenMode.CREATE) {
            // New index, so we just add the document (no old document can be there):
            System.out.println("adding " + file);
            writer.addDocument(doc);
        } else {
            // Existing index (an old copy of this document may have been indexed) so
            // we use updateDocument instead to replace the old one matching the exact
            // path, if present:
            System.out.println("updating " + file);
            writer.updateDocument(new Term("path", file.toString()), doc);
        }
    }
}

From source file:com.concursive.connect.web.modules.blog.dao.BlogPostIndexer.java

License:Open Source License

/**
 * Description of the Method//from  w w w.  ja v a2  s.c  o m
 *
 * @param writer   Description of the Parameter
 * @param item     Description of the Parameter
 * @param modified Description of the Parameter
 * @throws IOException Description of the Exception
 */
public void add(IndexWriter writer, Object item, boolean modified) throws IOException {
    BlogPost article = (BlogPost) item;
    // add the document
    Document document = new Document();
    document.add(new Field("type", "news", Field.Store.YES, Field.Index.UN_TOKENIZED));
    document.add(
            new Field("newsId", String.valueOf(article.getId()), Field.Store.YES, Field.Index.UN_TOKENIZED));
    document.add(new Field("projectId", String.valueOf(article.getProjectId()), Field.Store.YES,
            Field.Index.UN_TOKENIZED));
    if (article.getProjectId() > -1) {
        // use the project's general access to speedup guest projects
        Project project = ProjectUtils.loadProject(article.getProjectId());
        document.add(new Field("projectCategoryId", String.valueOf(project.getCategoryId()), Field.Store.YES,
                Field.Index.UN_TOKENIZED));
        document.add(new Field("guests", (project.getFeatures().getAllowGuests() ? "1" : "0"), Field.Store.YES,
                Field.Index.UN_TOKENIZED));
        document.add(new Field("participants", (project.getFeatures().getAllowParticipants() ? "1" : "0"),
                Field.Store.YES, Field.Index.UN_TOKENIZED));
        document.add(new Field("instanceId", String.valueOf(project.getInstanceId()), Field.Store.YES,
                Field.Index.UN_TOKENIZED));
        // determine if membership is needed for this content based on a guest's access to the data
        int membership = project.getFeatures().getMembershipRequired() ? 1 : 0;
        if (membership == 1
                && ProjectUtils.hasAccess(project.getId(), UserUtils.createGuestUser(), "project-news-view")) {
            membership = 0;
        }
        document.add(
                new Field("membership", String.valueOf(membership), Field.Store.YES, Field.Index.UN_TOKENIZED));
    }
    document.add(new Field("title", article.getSubject(), Field.Store.YES, Field.Index.TOKENIZED));
    document.add(new Field("titleLower", article.getSubject().toLowerCase(), Field.Store.YES,
            Field.Index.UN_TOKENIZED));
    document.add(new Field("contents",
            article.getSubject() + " " + ContentUtils.toText(ContentUtils.stripHTML(article.getIntro())) + " "
                    + ContentUtils.toText(ContentUtils.stripHTML(article.getMessage())),
            Field.Store.YES, Field.Index.TOKENIZED));
    if (article.getStartDate() != null) {
        document.add(new Field("modified", String.valueOf(article.getStartDate().getTime()), Field.Store.YES,
                Field.Index.UN_TOKENIZED));
        SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd");
        document.add(new Field("newsDate", String.valueOf(formatter.format(article.getStartDate())),
                Field.Store.YES, Field.Index.UN_TOKENIZED));
    } else {
        // If there is no date, set the date to an empty string to maintain the search.
        document.add(new Field("newsDate", "", Field.Store.YES, Field.Index.UN_TOKENIZED));
    }
    document.add(new Field("newsStatus", String.valueOf(article.getStatus()), Field.Store.YES,
            Field.Index.UN_TOKENIZED));
    document.add(new Field("newsClassificationId", String.valueOf(article.getClassificationId()),
            Field.Store.YES, Field.Index.UN_TOKENIZED));
    document.add(new Field("newsTemplateId", String.valueOf(article.getTemplateId()), Field.Store.YES,
            Field.Index.UN_TOKENIZED));
    if (article.getPortalKey() != null && !"".equals(article.getPortalKey())) {
        document.add(new Field("newsPortal", "true", Field.Store.YES, Field.Index.UN_TOKENIZED));
        document.add(
                new Field("newsPortalKey", article.getPortalKey(), Field.Store.YES, Field.Index.UN_TOKENIZED));
    }
    writer.addDocument(document);
    if (System.getProperty("DEBUG") != null && modified) {
        System.out.println("PostIndexer-> Added: " + article.getId());
    }
}

From source file:com.concursive.connect.web.modules.classifieds.dao.ClassifiedIndexer.java

License:Open Source License

/**
 * Description of the Method/*  w w  w.  j a v a  2s  .c o m*/
 *
 * @param writer   Description of the Parameter
 * @param item     Description of the Parameter
 * @param modified Description of the Parameter
 * @throws IOException Description of the Exception
 */
public void add(IndexWriter writer, Object item, boolean modified) throws IOException {
    Classified classified = (Classified) item;
    // add the document
    Document document = new Document();
    document.add(new Field("type", "classifieds", Field.Store.YES, Field.Index.UN_TOKENIZED));
    document.add(new Field("classifiedId", String.valueOf(classified.getId()), Field.Store.YES,
            Field.Index.UN_TOKENIZED));
    document.add(new Field("projectId", String.valueOf(classified.getProjectId()), Field.Store.YES,
            Field.Index.UN_TOKENIZED));
    if (classified.getCategoryId() != -1) {
        document.add(new Field("categoryId", String.valueOf(classified.getCategoryId()), Field.Store.YES,
                Field.Index.UN_TOKENIZED));
    }
    document.add(new Field("location",
            String.valueOf(ProjectUtils.loadProject(classified.getProjectId()).getLocation()), Field.Store.YES,
            Field.Index.TOKENIZED));
    document.add(new Field("instanceId",
            String.valueOf(ProjectUtils.loadProject(classified.getProjectId()).getInstanceId()),
            Field.Store.YES, Field.Index.UN_TOKENIZED));
    if (classified.getProjectId() > -1) {
        // use the project's general access to speedup guest projects
        Project project = ProjectUtils.loadProject(classified.getProjectId());
        document.add(new Field("projectCategoryId", String.valueOf(project.getCategoryId()), Field.Store.YES,
                Field.Index.UN_TOKENIZED));
        document.add(new Field("guests", (project.getFeatures().getAllowGuests() ? "1" : "0"), Field.Store.YES,
                Field.Index.UN_TOKENIZED));
        document.add(new Field("participants", (project.getFeatures().getAllowParticipants() ? "1" : "0"),
                Field.Store.YES, Field.Index.UN_TOKENIZED));
        // determine if membership is needed for this content based on a guest's access to the data
        int membership = project.getFeatures().getMembershipRequired() ? 1 : 0;
        if (membership == 1 && ProjectUtils.hasAccess(project.getId(), UserUtils.createGuestUser(),
                "project-classifieds-view")) {
            membership = 0;
        }
        document.add(
                new Field("membership", String.valueOf(membership), Field.Store.YES, Field.Index.UN_TOKENIZED));
    }
    document.add(new Field("title", classified.getTitle(), Field.Store.YES, Field.Index.TOKENIZED));
    document.add(new Field("titleFull", classified.getTitle(), Field.Store.YES, Field.Index.UN_TOKENIZED));
    document.add(new Field("titleLower", classified.getTitle().toLowerCase(), Field.Store.YES,
            Field.Index.UN_TOKENIZED));
    document.add(new Field("contents",
            classified.getTitle() + " " + ContentUtils.toText(classified.getDescription()), Field.Store.YES,
            Field.Index.TOKENIZED));
    SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd");
    if (classified.getPublishDate() != null) {
        document.add(new Field("modified", String.valueOf(formatter.format(classified.getPublishDate())),
                Field.Store.YES, Field.Index.UN_TOKENIZED));
        document.add(new Field("published", String.valueOf(formatter.format(classified.getPublishDate())),
                Field.Store.YES, Field.Index.UN_TOKENIZED));
    }
    if (classified.getExpirationDate() != null) {
        document.add(new Field("expired", String.valueOf(formatter.format(classified.getExpirationDate())),
                Field.Store.YES, Field.Index.UN_TOKENIZED));
    }
    writer.addDocument(document);
    if (System.getProperty("DEBUG") != null && modified) {
        System.out.println("ClassifiedIndexer-> Added: " + classified.getId());
    }
}

From source file:com.concursive.connect.web.modules.contacts.dao.ContactIndexer.java

License:Open Source License

/**
 * Description of the Method/*from  w  w  w  .java 2 s .  co  m*/
 *
 * @param writer   Description of the Parameter
 * @param item     Description of the Parameter
 * @param modified Description of the Parameter
 * @throws java.io.IOException Description of the Exception
 */
public void add(IndexWriter writer, Object item, boolean modified) throws IOException {
    Contact contact = (Contact) item;
    // add the document
    Document document = new Document();
    document.add(new Field("type", "contact", Field.Store.YES, Field.Index.UN_TOKENIZED));
    document.add(
            new Field("contactId", String.valueOf(contact.getId()), Field.Store.YES, Field.Index.UN_TOKENIZED));
    document.add(
            new Field("userId", String.valueOf(contact.getOwner()), Field.Store.YES, Field.Index.UN_TOKENIZED));
    document.add(new Field("title", contact.getIndexAs(), Field.Store.YES, Field.Index.TOKENIZED));
    document.add(new Field("titleLower", contact.getIndexAs().toLowerCase(), Field.Store.YES,
            Field.Index.UN_TOKENIZED));
    document.add(new Field("contents",
            contact.getIndexAs() + " " + contact.getComments() + " " + contact.getWebPage() + " "
                    + contact.getEmail1() + " " + contact.getEmail1() + " " + contact.getEmail2() + " "
                    + contact.getEmail3() + " ",
            Field.Store.YES, Field.Index.TOKENIZED));
    if (contact.getEntered() != null) {
        document.add(new Field("modified", String.valueOf(contact.getEntered().getTime()), Field.Store.YES,
                Field.Index.UN_TOKENIZED));
    }
    writer.addDocument(document);
    if (System.getProperty("DEBUG") != null && modified) {
        System.out.println("ContactIndexer-> Added: " + contact.getId());
    }
}

From source file:com.concursive.connect.web.modules.discussion.dao.ForumIndexer.java

License:Open Source License

/**
 * Description of the Method/*  w  ww  .j a v a 2  s . co  m*/
 *
 * @param writer   Description of the Parameter
 * @param item     Description of the Parameter
 * @param modified Description of the Parameter
 * @throws IOException Description of the Exception
 */
public void add(IndexWriter writer, Object item, boolean modified) throws IOException {
    Forum forum = (Forum) item;
    // use the project's general access to speedup guest projects
    Project project = ProjectUtils.loadProject(forum.getProjectId());
    // add the document
    Document document = new Document();
    document.add(new Field("type", "issuecategory", Field.Store.YES, Field.Index.UN_TOKENIZED));
    document.add(new Field("issueCategoryKeyId", String.valueOf(forum.getId()), Field.Store.YES,
            Field.Index.UN_TOKENIZED));
    document.add(new Field("issueCategoryId", String.valueOf(forum.getId()), Field.Store.YES,
            Field.Index.UN_TOKENIZED));
    document.add(new Field("projectId", String.valueOf(forum.getProjectId()), Field.Store.YES,
            Field.Index.UN_TOKENIZED));
    document.add(new Field("projectCategoryId", String.valueOf(project.getCategoryId()), Field.Store.YES,
            Field.Index.UN_TOKENIZED));
    document.add(new Field("guests", (project.getFeatures().getAllowGuests() ? "1" : "0"), Field.Store.YES,
            Field.Index.UN_TOKENIZED));
    document.add(new Field("participants", (project.getFeatures().getAllowParticipants() ? "1" : "0"),
            Field.Store.YES, Field.Index.UN_TOKENIZED));
    // determine if membership is needed for this content based on a guest's access to the data
    int membership = project.getFeatures().getMembershipRequired() ? 1 : 0;
    if (membership == 1 && ProjectUtils.hasAccess(project.getId(), UserUtils.createGuestUser(),
            "project-discussion-forums-view")) {
        membership = 0;
    }
    document.add(
            new Field("membership", String.valueOf(membership), Field.Store.YES, Field.Index.UN_TOKENIZED));
    document.add(new Field("title", forum.getSubject(), Field.Store.YES, Field.Index.TOKENIZED));
    document.add(new Field("titleLower", forum.getSubject().toLowerCase(), Field.Store.YES,
            Field.Index.UN_TOKENIZED));
    document.add(new Field("contents", forum.getSubject() + " " + ContentUtils.toText(forum.getDescription()),
            Field.Store.YES, Field.Index.TOKENIZED));
    if (modified) {
        document.add(new Field("modified", String.valueOf(System.currentTimeMillis()), Field.Store.YES,
                Field.Index.UN_TOKENIZED));
    } else {
        document.add(new Field("modified", String.valueOf(forum.getModified().getTime()), Field.Store.YES,
                Field.Index.UN_TOKENIZED));
    }
    writer.addDocument(document);
    if (System.getProperty("DEBUG") != null && modified) {
        LOG.debug("IssueCategoryIndexer->  Added: " + forum.getId());
    }
}

From source file:com.concursive.connect.web.modules.discussion.dao.ReplyIndexer.java

License:Open Source License

/**
 * Description of the Method//from   www .  ja  va  2  s. com
 *
 * @param writer   Description of the Parameter
 * @param item     Description of the Parameter
 * @param modified Description of the Parameter
 * @throws IOException Description of the Exception
 */
public void add(IndexWriter writer, Object item, boolean modified) throws IOException {
    Reply reply = (Reply) item;
    // use the project's general access to speedup guest projects
    Project project = ProjectUtils.loadProject(reply.getProjectId());
    // add the document
    Document document = new Document();
    document.add(new Field("type", "issuereply", Field.Store.YES, Field.Index.UN_TOKENIZED));
    document.add(new Field("issueReplyId", String.valueOf(reply.getId()), Field.Store.YES,
            Field.Index.UN_TOKENIZED));
    document.add(new Field("issueId", String.valueOf(reply.getIssueId()), Field.Store.YES,
            Field.Index.UN_TOKENIZED));
    document.add(new Field("issueCategoryId", String.valueOf(reply.getCategoryId()), Field.Store.YES,
            Field.Index.UN_TOKENIZED));
    document.add(new Field("projectId", String.valueOf(reply.getProjectId()), Field.Store.YES,
            Field.Index.UN_TOKENIZED));
    document.add(new Field("projectCategoryId", String.valueOf(project.getCategoryId()), Field.Store.YES,
            Field.Index.UN_TOKENIZED));
    document.add(new Field("guests", (project.getFeatures().getAllowGuests() ? "1" : "0"), Field.Store.YES,
            Field.Index.UN_TOKENIZED));
    document.add(new Field("participants", (project.getFeatures().getAllowParticipants() ? "1" : "0"),
            Field.Store.YES, Field.Index.UN_TOKENIZED));
    // determine if membership is needed for this content based on a guest's access to the data
    int membership = project.getFeatures().getMembershipRequired() ? 1 : 0;
    if (membership == 1 && ProjectUtils.hasAccess(project.getId(), UserUtils.createGuestUser(),
            "project-discussion-topics-view")) {
        membership = 0;
    }
    document.add(
            new Field("membership", String.valueOf(membership), Field.Store.YES, Field.Index.UN_TOKENIZED));
    document.add(new Field("title", reply.getSubject(), Field.Store.YES, Field.Index.TOKENIZED));
    document.add(new Field("titleLower", reply.getSubject().toLowerCase(), Field.Store.YES,
            Field.Index.UN_TOKENIZED));
    document.add(new Field("contents", reply.getSubject() + " " + ContentUtils.toText(reply.getBody()),
            Field.Store.YES, Field.Index.TOKENIZED));
    if (modified) {
        document.add(new Field("modified", String.valueOf(System.currentTimeMillis()), Field.Store.YES,
                Field.Index.UN_TOKENIZED));
    } else {
        document.add(new Field("modified", String.valueOf(reply.getModified().getTime()), Field.Store.YES,
                Field.Index.UN_TOKENIZED));
    }
    writer.addDocument(document);
    if (System.getProperty("DEBUG") != null && modified) {
        LOG.debug("IssueReplyIndexer Added: " + reply.getId());
    }
}

From source file:com.concursive.connect.web.modules.discussion.dao.TopicIndexer.java

License:Open Source License

/**
 * Description of the Method//from   w  w  w . j  a  v  a  2s .co m
 *
 * @param writer   Description of the Parameter
 * @param item     Description of the Parameter
 * @param modified Description of the Parameter
 * @throws IOException Description of the Exception
 */
public void add(IndexWriter writer, Object item, boolean modified) throws IOException {
    Topic topic = (Topic) item;
    // use the project's general access to speedup guest projects
    Project project = ProjectUtils.loadProject(topic.getProjectId());
    // add the document
    Document document = new Document();
    document.add(new Field("type", "issue", Field.Store.YES, Field.Index.UN_TOKENIZED));
    document.add(
            new Field("issueKeyId", String.valueOf(topic.getId()), Field.Store.YES, Field.Index.UN_TOKENIZED));
    document.add(
            new Field("issueId", String.valueOf(topic.getId()), Field.Store.YES, Field.Index.UN_TOKENIZED));
    document.add(new Field("issueCategoryId", String.valueOf(topic.getCategoryId()), Field.Store.YES,
            Field.Index.UN_TOKENIZED));
    document.add(new Field("projectId", String.valueOf(topic.getProjectId()), Field.Store.YES,
            Field.Index.UN_TOKENIZED));
    document.add(new Field("projectCategoryId", String.valueOf(project.getCategoryId()), Field.Store.YES,
            Field.Index.UN_TOKENIZED));
    document.add(new Field("guests", (project.getFeatures().getAllowGuests() ? "1" : "0"), Field.Store.YES,
            Field.Index.UN_TOKENIZED));
    document.add(new Field("participants", (project.getFeatures().getAllowParticipants() ? "1" : "0"),
            Field.Store.YES, Field.Index.UN_TOKENIZED));
    // determine if membership is needed for this content based on a guest's access to the data
    int membership = project.getFeatures().getMembershipRequired() ? 1 : 0;
    if (membership == 1 && ProjectUtils.hasAccess(project.getId(), UserUtils.createGuestUser(),
            "project-discussion-topics-view")) {
        membership = 0;
    }
    document.add(
            new Field("membership", String.valueOf(membership), Field.Store.YES, Field.Index.UN_TOKENIZED));
    document.add(new Field("title", topic.getSubject(), Field.Store.YES, Field.Index.TOKENIZED));
    document.add(new Field("titleLower", topic.getSubject().toLowerCase(), Field.Store.YES,
            Field.Index.UN_TOKENIZED));
    document.add(new Field("contents", topic.getSubject() + " " + ContentUtils.toText(topic.getBody()),
            Field.Store.YES, Field.Index.TOKENIZED));
    if (modified) {
        document.add(new Field("modified", String.valueOf(System.currentTimeMillis()), Field.Store.YES,
                Field.Index.UN_TOKENIZED));
    } else {
        document.add(new Field("modified", String.valueOf(topic.getModified().getTime()), Field.Store.YES,
                Field.Index.UN_TOKENIZED));
    }
    writer.addDocument(document);
    if (System.getProperty("DEBUG") != null && modified) {
        LOG.debug("IssueIndexer Added: " + topic.getId());
    }
}