Пример #1
0
        /// <summary>
        /// Converts a <see cref="Document" /> object to a <see cref="LuceneDocument" /> object.
        /// </summary>
        /// <param name="document">The Document object</param>
        /// <param name="schema">The schema.</param>
        /// <param name="facetBuilder">The Lucene facet builder.</param>
        /// <returns></returns>
        /// <exception cref="ArgumentNullException"></exception>
        /// <exception cref="InvalidOperationException">Cannot index a Document that does not have an _id.</exception>
        /// <exception cref="SchemaException">The fieldName '{fieldName}'</exception>
        /// <exception cref="System.ArgumentNullException"></exception>
        /// <exception cref="System.InvalidOperationException">Cannot index a Document that does not have an _id.</exception>
        public static LuceneDocument ToLuceneDocument(this Document document, Schema schema = null, LuceneFacetBuilder facetBuilder = null)
        {
            if (document == null)
                throw new ArgumentNullException(nameof(document));
            if (schema == null)
                schema = Schema.CreateDefault();

            var documentDictionary = document.AsDictionary();
            if (!documentDictionary.ContainsKey(Schema.StandardField.ID))
                throw new InvalidOperationException("Cannot index a Document that does not have an _id.");

            var luceneDocument = new LuceneDocument();

            // Make sure the _id field is the first field added to the Lucene document
            var keys = documentDictionary.Keys.Except(new[] { Schema.StandardField.ID }).ToList();
            keys.Insert(0, Schema.StandardField.ID);

            foreach (var fieldName in keys)
            {
                // Validate fieldName - must not contain space or Lucene QueryParser illegal characters.
                if (_queryParserIllegalCharsRegex.IsMatch(fieldName))
                    throw new SchemaException($"The fieldName '{fieldName}' contains illegal characters.");

                Schema.Field schemaField = null;
                if (!schema.Fields.TryGetValue(fieldName, out schemaField))
                {
                    schemaField = new Schema.Field
                    {
                        Name = fieldName
                    };
                    schema.Fields.TryAdd(fieldName, schemaField);
                }

                var fieldValue = documentDictionary[fieldName];
                var luceneFields = fieldValue.ToLuceneFields(schemaField);
                foreach (var luceneField in luceneFields)
                    luceneDocument.Add(luceneField);
            }

            // The full-text field is always auto-generated and added to the Lucene document.
            var fullText = document.ToLuceneFullTextString();
            luceneDocument.Add(new TextField(Schema.StandardField.FULL_TEXT, fullText, FieldStore.NO));

            // Check if the document has the special _categories field,
            // which means that we need to create facets for it.
            if (document.HasCategories() && facetBuilder != null)
                luceneDocument = facetBuilder.RebuildDocumentWithFacets(luceneDocument, document, schema);

            return luceneDocument;
        }
Пример #2
0
        /// <summary>
        /// Initializes a new instance of the <see cref="LuceneIndex" /> class.
        /// </summary>
        /// <param name="indexPath">The path to the directory that will contain the Lucene index files.</param>
        /// <param name="schema">The schema.</param>
        /// <exception cref="System.ArgumentNullException"></exception>
        public LuceneIndex(string indexPath, Schema schema)
        {
            if (String.IsNullOrWhiteSpace(indexPath))
                throw new ArgumentNullException(nameof(indexPath)); 
            if (schema == null)
                throw new ArgumentNullException(nameof(schema));

            IndexPath = indexPath;
            Schema = schema;

            if (System.IO.Directory.Exists(IndexPath))
            {
                if (Schema.IsDefault())
                    throw new InvalidOperationException($"There is an existing index on '{IndexPath}'.");
            }                
            else
            {
                System.IO.Directory.CreateDirectory(IndexPath);
            }                        

            _indexDirectory = new MMapDirectory(Paths.get(IndexPath));

            var taxonomyIndexPath = System.IO.Path.Combine(IndexPath, "taxonomy");
            if (!System.IO.Directory.Exists(taxonomyIndexPath))            
                System.IO.Directory.CreateDirectory(taxonomyIndexPath);

            _taxonomyDirectory = new MMapDirectory(Paths.get(taxonomyIndexPath));         
                           
            _compositeAnalyzer = new CompositeAnalyzer(Schema);            

            _ramBufferSizeMB = Double.Parse(ConfigurationManager.AppSettings["IndexWriter.RAMBufferSizeMB"] ?? "128");

            var config = new IndexWriterConfig(_compositeAnalyzer)                            
                            .SetOpenMode(IndexWriterConfigOpenMode.CREATE_OR_APPEND)
                            .SetRAMBufferSizeMB(_ramBufferSizeMB)
                            .SetCommitOnClose(true);                            
            
            _indexWriter = new IndexWriter(_indexDirectory, config);
            _taxonomyWriter = new DirectoryTaxonomyWriter(_taxonomyDirectory, IndexWriterConfigOpenMode.CREATE_OR_APPEND);

            _searcherTaxonomyManager = new SearcherTaxonomyManager(_indexWriter, true, null, _taxonomyWriter);            
            _facetBuilder = new LuceneFacetBuilder(_taxonomyWriter);                        

            _refreshIntervalSeconds = Double.Parse(ConfigurationManager.AppSettings["IndexSearcher.RefreshIntervalSeconds"] ?? "0.5");    
            _commitIntervalSeconds = Double.Parse(ConfigurationManager.AppSettings["IndexWriter.CommitIntervalSeconds"] ?? "60");
           
            _writeAllowedFlag = new ManualResetEventSlim(true);

            _refreshTimer = new Timer(o => Refresh(), null, TimeSpan.FromSeconds(_refreshIntervalSeconds), TimeSpan.FromSeconds(_refreshIntervalSeconds));
            _commitTimer = new Timer(o => Commit(), null, TimeSpan.FromSeconds(_commitIntervalSeconds), TimeSpan.FromSeconds(_commitIntervalSeconds));

        }