GroupDocs.Search supports indexing of many document formats. In addition, you can implement support for any other format, or replace the built-in extraction for a supported format, with a custom text extractor.
A custom text extractor is a class implementing the IFieldExtractor interface. In Python, it is a plain class with the members of the interface; do not derive it from the IFieldExtractor class. The extensions attribute lists the file extensions the extractor is used for, and the get_fields method extracts the fields of a document from a file or from a stream. For a file, the method receives the path to the file as a str; for a document added from a stream, it receives the stream, whose read() method returns the bytes of the document. The method returns a list of DocumentField objects or (name, value) tuples.
The following example demonstrates how to implement a custom text extractor.
importdatetimeimportosfromgroupdocs.search.commonimportDocumentFieldclassLogExtractor(object):extensions=[".log"]defget_fields(self,source):ifisinstance(source,str):# The document is a file: source is the path to the filecreation_time=datetime.datetime.fromtimestamp(os.path.getctime(source))return[DocumentField("FileName",os.path.abspath(source)),DocumentField("CreationDate",creation_time.strftime("%m/%d/%Y %H:%M:%S")),DocumentField("Content",self.extract_content(source)),]# The document is a stream: source.read() returns its bytes# The stream belongs to the caller, so it is not closed herereturn[DocumentField("Content",source.read().decode("utf-8-sig"))]defextract_content(self,file_path):withopen(file_path,encoding="utf-8-sig")asf:returnf.read()
To use a custom extractor, add it to the custom_extractors collection of the index settings. A custom extractor takes precedence over the built-in extractor for the same extension. Custom extractors are not saved in an index, so they must be added each time the index is created or opened. The next example shows how to use the custom extractor for indexing.
importdatetimeimportosfromgroupdocs.searchimportIndex,IndexSettingsfromgroupdocs.search.commonimportDocumentFieldclassLogExtractor(object):extensions=[".log"]defget_fields(self,source):ifisinstance(source,str):creation_time=datetime.datetime.fromtimestamp(os.path.getctime(source))return[DocumentField("FileName",os.path.abspath(source)),DocumentField("CreationDate",creation_time.strftime("%m/%d/%Y %H:%M:%S")),DocumentField("Content",self.extract_content(source)),]return[DocumentField("Content",source.read().decode("utf-8-sig"))]defextract_content(self,file_path):withopen(file_path,encoding="utf-8-sig")asf:returnf.read()settings=IndexSettings()settings.custom_extractors.add(LogExtractor())# Adding custom text extractor to the index settingsindex=Index("./index",settings)# Creating or loading an indexindex.add("./documents")# Indexing documents from the specified folderresult=index.search("quota")# Searching for a word from the log fileprint("Documents found:",result.document_count)
To index a container document (for example, an archive) whose items are indexed as separate items of the document, implement the IContainerItemExtractor interface. In addition to the members of IFieldExtractor, this interface contains:
The format_family attribute, the format family of the container document: a constant of the FormatFamily class, for example FormatFamily.ARCHIVE.
The get_container_items method, which extracts the items of a container document from a file or from a stream (it receives a path or a stream, as get_fields does) and returns them as a list of ExtractedItemInfo objects or (format_family, fields, item_info, inner_path) tuples.
Each ExtractedItemInfo object describes one item: its format_family, the extracted fields, the item_info string that identifies the item in the container, and the inner_path of the item. Items with an empty item_info value are not indexed. The fields returned by get_fields are indexed as the fields of the container document itself. The indexed items of a container document can be obtained with the get_indexed_document_items method.
The following example demonstrates a custom extractor that indexes each line of a text file as a separate item. The example then indexes a folder with such files and prints the indexed items; the item_info string of an item is the inner_path of its DocumentInfo.
importosfromgroupdocs.searchimportIndex,IndexSettingsfromgroupdocs.search.commonimportDocumentField,ExtractedItemInfofromgroupdocs.search.resultsimportFormatFamilyclassLineContainerExtractor(object):extensions=[".lines"]format_family=FormatFamily.ARCHIVEdefget_fields(self,source):ifisinstance(source,str):# The container document itself has only the file name fieldreturn[DocumentField("FileName",os.path.basename(source))]return[]defget_container_items(self,source):ifisinstance(source,str):withopen(source,encoding="utf-8-sig")asf:lines=f.read().splitlines()else:lines=source.read().decode("utf-8-sig").splitlines()returnself.create_items(lines)@staticmethoddefcreate_items(lines):items=[]fori,lineinenumerate(lines):fields=[DocumentField("Content",line)]item_info="Line "+str(i+1)items.append(ExtractedItemInfo(FormatFamily.WORD_PROCESSING,fields,item_info,""))returnitems# Indexing the lines of the .lines files as separate itemssettings=IndexSettings()settings.custom_extractors.add(LineContainerExtractor())index=Index("./index",settings)index.add("./documents")# Getting the indexed items of each container documentfordocumentinindex.get_indexed_documents():print(os.path.basename(document.file_path))foriteminindex.get_indexed_document_items(document):print("\t"+item.inner_path)# Searching in the itemsresult=index.search("Venus")forfoundinresult:print("Found in:",found.document_info.inner_path)
Along with the full-featured library, we provide a free online document search app. You are welcome to search over your PDF, DOC, DOCX, PPT, PPTX, XLS, XLSX and more with our Free Online Document Search App.
Was this page helpful?
Any additional feedback you'd like to share with us?
Please tell us how we can improve this page.
Thank you for your feedback!
We value your opinion. Your feedback will help us improve our documentation.
Analyzing your prompt, please hold on...
An error occurred while retrieving the results. Please refresh the page and try again.