com.orientechnologies.lucene.manager.OLuceneFullTextIndexManager.java Source code

Java tutorial

Introduction

Here is the source code for com.orientechnologies.lucene.manager.OLuceneFullTextIndexManager.java

Source

/*
 * Copyright 2014 Orient Technologies.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.orientechnologies.lucene.manager;

import com.orientechnologies.common.log.OLogManager;
import com.orientechnologies.lucene.OLuceneIndexType;
import com.orientechnologies.lucene.collections.LuceneResultSet;
import com.orientechnologies.lucene.collections.OFullTextCompositeKey;
import com.orientechnologies.lucene.query.QueryContext;
import com.orientechnologies.orient.core.command.OCommandContext;
import com.orientechnologies.orient.core.db.record.OIdentifiable;
import com.orientechnologies.orient.core.id.OContextualRecordId;
import com.orientechnologies.orient.core.index.*;
import com.orientechnologies.orient.core.record.impl.ODocument;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.queryparser.classic.ParseException;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.store.Directory;
import org.apache.lucene.util.Version;

import java.io.IOException;
import java.util.*;

public class OLuceneFullTextIndexManager extends OLuceneIndexManagerAbstract {

    protected OLuceneFacetManager facetManager;

    public OLuceneFullTextIndexManager() {
    }

    @Override
    public IndexWriter createIndexWriter(Directory directory, ODocument metadata) throws IOException {

        Analyzer analyzer = getAnalyzer(metadata);
        Version version = getLuceneVersion(metadata);
        IndexWriterConfig iwc = new IndexWriterConfig(version, analyzer);
        iwc.setOpenMode(IndexWriterConfig.OpenMode.CREATE_OR_APPEND);

        facetManager = new OLuceneFacetManager(this, metadata);

        OLogManager.instance().debug(this, "Creating Lucene index in '%s'...", directory);

        return new IndexWriter(directory, iwc);
    }

    @Override
    public IndexWriter openIndexWriter(Directory directory, ODocument metadata) throws IOException {
        Analyzer analyzer = getAnalyzer(metadata);
        Version version = getLuceneVersion(metadata);
        IndexWriterConfig iwc = new IndexWriterConfig(version, analyzer);
        iwc.setOpenMode(IndexWriterConfig.OpenMode.APPEND);

        OLogManager.instance().debug(this, "Opening Lucene index in '%s'...", directory);

        return new IndexWriter(directory, iwc);
    }

    @Override
    public void init() {

    }

    @Override
    public boolean contains(Object key) {
        return false;
    }

    @Override
    public boolean remove(Object key) {
        return false;
    }

    @Override
    public Object get(Object key) {
        Query q = null;
        try {
            q = OLuceneIndexType.createFullQuery(index, key, mgrWriter.getIndexWriter().getAnalyzer(),
                    getLuceneVersion(metadata));
            OCommandContext context = null;
            if (key instanceof OFullTextCompositeKey) {
                context = ((OFullTextCompositeKey) key).getContext();
            }
            return getResults(q, context, key);
        } catch (ParseException e) {
            throw new OIndexEngineException("Error parsing lucene query ", e);
        }
    }

    @Override
    public void put(Object key, Object value) {
        Set<OIdentifiable> container = (Set<OIdentifiable>) value;
        for (OIdentifiable oIdentifiable : container) {
            Document doc = new Document();
            doc.add(OLuceneIndexType.createField(RID, oIdentifiable.getIdentity().toString(), Field.Store.YES,
                    Field.Index.NOT_ANALYZED_NO_NORMS));
            int i = 0;
            if (index.isAutomatic()) {
                for (String f : index.getFields()) {

                    Object val = null;
                    if (key instanceof OCompositeKey) {
                        val = ((OCompositeKey) key).getKeys().get(i);
                        i++;
                    } else {
                        val = key;
                    }
                    if (val != null) {
                        if (facetManager.supportsFacets() && facetManager.isFacetField(f)) {
                            doc.add(facetManager.buildFacetField(f, val));
                        } else {

                            if (isToStore(f).equals(Field.Store.YES)) {
                                doc.add(OLuceneIndexType.createField(f + STORED, val, Field.Store.YES,
                                        Field.Index.NOT_ANALYZED_NO_NORMS));
                            }
                            doc.add(OLuceneIndexType.createField(f, val, Field.Store.NO, Field.Index.ANALYZED));
                        }
                    }

                }
            } else {

                Object val = null;
                if (key instanceof OCompositeKey) {
                    List<Object> keys = ((OCompositeKey) key).getKeys();
                    int k = 0;
                    for (Object o : keys) {
                        doc.add(OLuceneIndexType.createField("k" + k, o, Field.Store.NO, Field.Index.ANALYZED));
                        k++;
                    }
                } else if (key instanceof Collection) {
                    Collection<Object> keys = (Collection<Object>) key;
                    int k = 0;
                    for (Object o : keys) {
                        doc.add(OLuceneIndexType.createField("k" + k, o, Field.Store.NO, Field.Index.ANALYZED));
                        k++;
                    }
                } else {
                    val = key;
                    doc.add(OLuceneIndexType.createField("k0", val, Field.Store.NO, Field.Index.ANALYZED));
                }
            }
            if (facetManager.supportsFacets()) {
                try {
                    addDocument(facetManager.buildDocument(doc));
                } catch (IOException e) {
                    e.printStackTrace();
                }
            } else {
                addDocument(doc);
            }

            facetManager.commit();

            if (!index.isAutomatic()) {
                commit();
            }
        }
    }

    private Set<OIdentifiable> getResults(Query query, OCommandContext context, Object key) {

        try {
            IndexSearcher searcher = getSearcher();
            QueryContext queryContext = new QueryContext(context, searcher, query);
            if (facetManager.supportsFacets()) {
                facetManager.addFacetContext(queryContext, key);
            }
            return new LuceneResultSet(this, queryContext);
        } catch (IOException e) {
            throw new OIndexException("Error reading from Lucene index", e);
        }

    }

    @Override
    public void onRecordAddedToResultSet(QueryContext queryContext, OContextualRecordId recordId, Document ret,
            final ScoreDoc score) {
        recordId.setContext(new HashMap<String, Object>() {
            {
                put("score", score.score);
            }
        });
    }

    @Override
    public Object getFirstKey() {
        return null;
    }

    @Override
    public Object getLastKey() {
        return null;
    }

    @Override
    public OIndexCursor iterateEntriesBetween(Object rangeFrom, boolean fromInclusive, Object rangeTo,
            boolean toInclusive, boolean ascSortOrder, ValuesTransformer transformer) {
        return new LuceneIndexCursor((LuceneResultSet) get(rangeFrom), rangeFrom);
    }

    @Override
    public OIndexCursor iterateEntriesMajor(Object fromKey, boolean isInclusive, boolean ascSortOrder,
            ValuesTransformer transformer) {
        return null;
    }

    @Override
    public OIndexCursor iterateEntriesMinor(Object toKey, boolean isInclusive, boolean ascSortOrder,
            ValuesTransformer transformer) {
        return null;
    }

    @Override
    public OIndexCursor cursor(ValuesTransformer valuesTransformer) {
        return null;
    }

    @Override
    public OIndexKeyCursor keyCursor() {
        return new OIndexKeyCursor() {
            @Override
            public Object next(int prefetchSize) {
                return null;
            }
        };
    }

    @Override
    public boolean hasRangeQuerySupport() {
        return false;
    }

    @Override
    public int getVersion() {
        return 0;
    }

    @Override
    public Document buildDocument(Object key, OIdentifiable value) {
        return build(index, key, value, metadata);
    }

    @Override
    public Query buildQuery(Object query) throws ParseException {
        return OLuceneIndexType.createFullQuery(index, query, mgrWriter.getIndexWriter().getAnalyzer(),
                getLuceneVersion(metadata));

    }

    @Override
    public Analyzer analyzer(String field) {
        return getAnalyzer(metadata);
    }

    protected Document build(OIndexDefinition definition, Object key, OIdentifiable value, ODocument metadata) {
        Document doc = new Document();
        int i = 0;

        if (value != null) {
            doc.add(OLuceneIndexType.createField(OLuceneIndexManagerAbstract.RID, value.getIdentity().toString(),
                    Field.Store.YES, Field.Index.NOT_ANALYZED_NO_NORMS));
        }
        List<Object> formattedKey = formatKeys(definition, key);
        for (String f : definition.getFields()) {
            Object val = formattedKey.get(i);
            i++;
            if (val != null)
                doc.add(OLuceneIndexType.createField(f, val, Field.Store.NO, Field.Index.ANALYZED));
        }
        return doc;
    }

    private List<Object> formatKeys(OIndexDefinition definition, Object key) {
        List<Object> keys;

        if (key instanceof OCompositeKey) {
            keys = ((OCompositeKey) key).getKeys();

        } else if (key instanceof List) {
            keys = ((List) key);
        } else {
            keys = new ArrayList<Object>();
            keys.add(key);
        }

        for (int i = keys.size(); i < definition.getFields().size(); i++) {
            keys.add("");
        }
        return keys;
    }

    @Override
    public void delete() {
        super.delete();
        facetManager.delete();
    }

    public class LuceneIndexCursor implements OIndexCursor {

        private final Object key;
        private LuceneResultSet resultSet;

        private Iterator<OIdentifiable> iterator;

        public LuceneIndexCursor(LuceneResultSet resultSet, Object key) {
            this.resultSet = resultSet;
            this.iterator = resultSet.iterator();
            this.key = key;
        }

        @Override
        public Map.Entry<Object, OIdentifiable> nextEntry() {

            if (iterator.hasNext()) {
                final OIdentifiable next = iterator.next();
                return new Map.Entry<Object, OIdentifiable>() {
                    @Override
                    public Object getKey() {
                        return key;
                    }

                    @Override
                    public OIdentifiable getValue() {
                        return next;
                    }

                    @Override
                    public OIdentifiable setValue(OIdentifiable value) {
                        return null;
                    }
                };
            }
            return null;
        }

        @Override
        public Set<OIdentifiable> toValues() {
            return null;
        }

        @Override
        public Set<Map.Entry<Object, OIdentifiable>> toEntries() {
            return null;
        }

        @Override
        public Set<Object> toKeys() {
            return null;
        }

        @Override
        public void setPrefetchSize(int prefetchSize) {

        }

        @Override
        public boolean hasNext() {
            return false;
        }

        @Override
        public OIdentifiable next() {
            return null;
        }

        @Override
        public void remove() {

        }

    }

}