Как реализовать поиск файлов по их названию и расширению,используя Lucene на C#?
Вроде как индексировал и само содержимое файлов, и их имена, но что-то с поиском по второму никак не клеется... Пробовал многое, но результатов нет. Код немного обрезал и прокомментировал на "профанском" уровне
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Lucene.Net.Index;
using Lucene.Net.Analysis.Standard;
using Lucene.Net.Analysis.Snowball;
using Lucene.Net.Analysis;
using Lucene.Net.Documents;
using Lucene.Net;
using Lucene.Net.Store;
using Lucene.Net.QueryParsers;
using Lucene.Net.Search;
namespace Test
{
public partial class Form1 : Form
{
public DataTable _dataTable = new DataTable(); //объъявление таблицы
public IndexWriter writer; //глобальный создатель индекса
public Lucene.Net.Store.Directory directoryStandart; //директория стандартного индекса
public Lucene.Net.Store.Directory directorySnowball; //директория стемминга индекса
public string pathSourceFile; //директория, которую индексировать
public Analyzer standart; //объявление имени стандартного анализатора
public Analyzer snow; //объявление имени анализатора стемминга
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
_dataTable.Columns.Add(new DataColumn("№", typeof(int))); //добавление колоки с номером
_dataTable.Columns.Add(new DataColumn("Путь к папке с индексами", typeof(string))); //добавление колоки с путем
dataGridView1.DataSource = _dataTable; //присваем месту для таблицы саму таблицу
standart = new StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_30);// морфологический анализатор
//осуществляет приведение символов к нижнему регистру, удаление общих слов и знаков пунктуации
snow = new SnowballAnalyzer(Lucene.Net.Util.Version.LUCENE_30, "English"); //анализатор стемминга
}
private void button1_Click(object sender, EventArgs e)
{
FolderBrowserDialog FBD = new FolderBrowserDialog(); //вызываем выбор директории
if (FBD.ShowDialog() == DialogResult.OK) //если директория выбрана
{
_dataTable.Rows.Add(_dataTable.Rows.Count + 1, FBD.SelectedPath); //добавляем к таблице строку
//с выбранным путем
directoryStandart = FSDirectory.Open(FBD.SelectedPath); //присваиваем переменной путь к папке
//для хранения стандартного индекса
}
}
private void button2_Click(object sender, EventArgs e)
{
FolderBrowserDialog FBD = new FolderBrowserDialog(); //вызываем выбор директории
if (FBD.ShowDialog() == DialogResult.OK) //если директория выбрана
{
_dataTable.Rows.Add(_dataTable.Rows.Count + 1, FBD.SelectedPath); //добавляем к таблице строку
//с выбранным путем
directorySnowball = FSDirectory.Open(FBD.SelectedPath);//присваиваем переменной путь к папке
//для сохранения индекса Стемминга
}
}
private void button3_Click(object sender, EventArgs e)
{
FolderBrowserDialog FBD = new FolderBrowserDialog(); //вызываем выбор директории
if (FBD.ShowDialog() == DialogResult.OK) //если директория выбрана
{
pathSourceFile = FBD.SelectedPath;//присваиваем переменной путь к папке
//для индексации
}
indexing(directoryStandart, standart);
indexing(directorySnowball, snow);
text1.Text = "Выполнено!";
}
private void indexing(Lucene.Net.Store.Directory directory, Analyzer analyzer)
{
IndexWriter writer = new IndexWriter(directory, analyzer, IndexWriter.MaxFieldLength.UNLIMITED); //создание индекса
//В качестве параметров конструктору класса передаются следующие параметры: путь к директории индекса,
//объект морфологического анализатора, а также максимальная длина индексируемого поля
string[] files = System.IO.Directory.GetFiles(pathSourceFile); //объявление места
//откуда считаваются файлы для индексирование
foreach (var file in files)//пока есть файлы
{
string text = System.IO.File.ReadAllText(file);//выделеение текста
string name = System.IO.Path.GetFileName(file);//выделение имени
Document doc = new Document(); //Создание экземпляра класса
doc.Add(new Field("name", name, Field.Store.YES, Field.Index.ANALYZED)); //хранить индексе имя файла и анализировать
doc.Add(new Field("text", text, Field.Store.YES, Field.Index.ANALYZED));
writer.AddDocument(doc); //Добавление документв
}
writer.Optimize();
writer.Dispose();
}
private void button4_Click(object sender, EventArgs e)
{
OutStandart.Text = "";
OutStamming.Text = "";
multiSeach();
}
public void multiSeach()
{
// так как по одному слову, подаем сразу же это слово
char[] array = { ' ' };
List<string> queryStr = new List<string>();
queryStr.AddRange(Search.Text.Split(array, StringSplitOptions.RemoveEmptyEntries));
if (queryStr.Count > 1)
{
throw new Exception("Введите одно слово");
}
else
{
IndexSearcher indexSearcher1 = new IndexSearcher(directoryStandart);
IndexSearcher indexSearcher2 = new IndexSearcher(directorySnowball);
//поиск файлов по индексу
Lucene.Net.Search.TopDocs results1 = indexSearcher1.Search(new TermQuery(
new Lucene.Net.Index.Term("text", queryStr[0])), null, Int32.MaxValue);
Lucene.Net.Search.TopDocs results2 = indexSearcher2.Search(new TermQuery(
new Lucene.Net.Index.Term("text", queryStr[0])), null, Int32.MaxValue);
//получаем список файлов
showResult(indexSearcher1, results1, OutStandart);
showResult(indexSearcher2, results2, OutStamming);
}
}
Ответы (2 шт):
Чем вам стандартные методы Net Framework не подходят? System.IO.Directory.GetFiles(@"C:\", @"*.exe").ToList().ForEach(f => Console.WriteLine(f));
Дело в том, что вопрос был поставлен при условии, что должен использоваться Lucene. Ответы и комментарии, которые давались использовали другие библиотеки и функции, которые не соответствуют требованиям для реализации проекта в дальнейшей перспективе. Если говорить проще, ответы давались не совсем по теме.
Теперь к решению. Код рабочий, но в этой строке:
string name = System.IO.Path.GetFileName(file);
Происходило извлечение имени файла вместе с расширением (text.txt). Я думал, что извлекается просто имя (text) и в поиске забивал не то, что надо. Поэтому и думал, что код не рабочий.
Следовательно для решения вопроса потребовалось применить функции извлечения только имени и только расширения. После этого для каждого из наборов построить индекс и всё.