org.remus.marketplace.indexing.impl.IndexServiceImpl.java Source code

Java tutorial

Introduction

Here is the source code for org.remus.marketplace.indexing.impl.IndexServiceImpl.java

Source

/*******************************************************************************
 * Copyright (c) 2010 Tom Seidel, Remus Software
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 *
 * Contributors:
 *     Tom Seidel - initial API and implementation
 *******************************************************************************/
package org.remus.marketplace.indexing.impl;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.SimpleAnalyzer;
import org.apache.lucene.analysis.WhitespaceAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriter.MaxFieldLength;
import org.apache.lucene.index.Term;
import org.apache.lucene.queryParser.MultiFieldQueryParser;
import org.apache.lucene.search.BooleanClause.Occur;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.Sort;
import org.apache.lucene.search.TopFieldDocs;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;
import org.remus.marketplace.entities.Category;
import org.remus.marketplace.entities.Node;
import org.remus.marketplace.indexing.IndexService;

/**
 * @author Tom Seidel <tom.seidel@remus-software.org>
 */
public class IndexServiceImpl implements IndexService {

    private String indexDir;

    public void setIndexDir(String indexDir) {
        this.indexDir = indexDir;
    }

    @Override
    public void addToIndex(Node node) {
        try {

            Map<Integer, String> listOfCat = new HashMap<Integer, String>();
            Set<Category> categories = node.getCategories();
            for (Category category : categories) {
                if (!listOfCat.containsKey(category.getId())) {
                    listOfCat.put(category.getId(), category.getMarket().getId());
                }
            }

            IndexWriter indexWriter = new IndexWriter(getDirectory(), new SimpleAnalyzer(),
                    MaxFieldLength.UNLIMITED);
            Set<Integer> keySet = listOfCat.keySet();
            indexWriter.deleteDocuments(new Term(Node.ID, String.valueOf(node.getId())));
            for (Integer integer : keySet) {
                final Document document = new Document();

                Field unitField = new Field(Node.ID, String.valueOf(node.getId()), Field.Store.YES,
                        Field.Index.NOT_ANALYZED);
                document.add(unitField);

                Field titleField = new Field(Node.NAME, node.getName(), Field.Store.YES, Field.Index.ANALYZED);
                document.add(titleField);
                titleField.setBoost(2.0f);

                Field shortDescriptionField = new Field(Node.SHORTDESCRIPTION, node.getShortdescription(),
                        Field.Store.YES, Field.Index.ANALYZED);
                document.add(shortDescriptionField);
                shortDescriptionField.setBoost(1.5f);

                Field bodyField = new Field(Node.BODY, node.getBody(), Field.Store.YES, Field.Index.ANALYZED);
                bodyField.setBoost(1.0f);
                document.add(bodyField);

                Field categoryField = new Field("category", String.valueOf(integer), Field.Store.YES,
                        Field.Index.NOT_ANALYZED);
                document.add(categoryField);

                Field marketField = new Field("market", listOfCat.get(integer), Field.Store.YES,
                        Field.Index.NOT_ANALYZED);
                document.add(marketField);

                indexWriter.addDocument(document);
            }

            indexWriter.commit();
            indexWriter.optimize();
            indexWriter.close();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

    }

    @Override
    public void removeFromIndex(Node node) {
        final Term term = new Term(Node.ID, String.valueOf(node.getId()));
        try {
            IndexWriter indexWriter = new IndexWriter(getDirectory(), new SimpleAnalyzer(),
                    MaxFieldLength.UNLIMITED);
            indexWriter.deleteDocuments(term);
            indexWriter.commit();
            indexWriter.optimize();
            indexWriter.close();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

    }

    @Override
    public List<Integer> searchNodes(String query, int categoryId, String marketId) {
        List<Integer> returnValue = new ArrayList<Integer>();

        List<String> termList = new ArrayList<String>();
        List<String> fieldList = new ArrayList<String>();
        List<Occur> flagList = new ArrayList<Occur>();
        Query searchWordQuery = null;

        try {
            IndexSearcher indexSearcher = new IndexSearcher(getDirectory());

            // search for the query

            if (query != null && query.length() > 0) {
                fieldList.add(Node.NAME);
                termList.add(query);
                flagList.add(Occur.SHOULD);

                fieldList.add(Node.SHORTDESCRIPTION);
                termList.add(query);
                flagList.add(Occur.SHOULD);

                fieldList.add(Node.BODY);
                termList.add(query);
                flagList.add(Occur.SHOULD);
            }

            if (fieldList.size() > 0) {
                searchWordQuery = MultiFieldQueryParser.parse(Version.LUCENE_30,
                        termList.toArray(new String[termList.size()]),
                        fieldList.toArray(new String[fieldList.size()]),
                        flagList.toArray(new Occur[flagList.size()]), getAnalyser());
            }

            // must part
            // Must part
            termList = new ArrayList<String>();
            fieldList = new ArrayList<String>();
            flagList = new ArrayList<Occur>();

            if (categoryId > 0) {
                fieldList.add("category");
                termList.add(String.valueOf(categoryId));
                flagList.add(Occur.MUST);
            }
            if (categoryId > 0) {
                fieldList.add("category");
                termList.add(String.valueOf(categoryId));
                flagList.add(Occur.MUST);
            }

            Query mustHaveQuery = null;

            if (fieldList.size() > 0) {
                mustHaveQuery = MultiFieldQueryParser.parse(Version.LUCENE_30,
                        termList.toArray(new String[termList.size()]),
                        fieldList.toArray(new String[fieldList.size()]),
                        flagList.toArray(new Occur[flagList.size()]), getAnalyser());
            }

            BooleanQuery booleanQuery = new BooleanQuery();
            if (searchWordQuery != null) {
                booleanQuery.add(searchWordQuery, Occur.MUST);
            }
            if (mustHaveQuery != null && termList.size() > 0) {
                booleanQuery.add(mustHaveQuery, Occur.MUST);
            }

            TopFieldDocs search = indexSearcher.search(booleanQuery, null, 4096, new Sort());
            ScoreDoc[] scoreDocs = search.scoreDocs;
            for (ScoreDoc scoreDoc : scoreDocs) {
                Document doc = indexSearcher.doc(scoreDoc.doc);
                int parseInt = Integer.parseInt(doc.get(Node.ID));
                if (!returnValue.contains(parseInt)) {
                    returnValue.add(parseInt);
                }
            }
            indexSearcher.close();

            return returnValue;

        } catch (Exception e) {
            throw new RuntimeException(e);
        }

    }

    private Directory getDirectory() throws IOException {
        File file = new File(indexDir);
        if (!file.exists()) {
            file.mkdirs();
        }
        return FSDirectory.open(file);
    }

    private Analyzer getAnalyser() {
        return new WhitespaceAnalyzer();
    }

}