spring boot +vue+lucene+tika实现一个类似于百度文库的文件检索功能

spring boot +vue+lucene+tika实现一个类似于百度文库的文件检索功能

需求分析

在这里插入图片描述

根据需求,我们需要实现一个类似于百度文库的文件检索功能。以下是功能的分解:

  1. 需求分析

    • 用户上传文件(如PDF、Word、Excel等)。
    • 系统对文件内容进行索引(使用Lucene)。
    • 用户可以通过关键词搜索文件内容。
    • 搜索结果展示文件名、摘要信息以及匹配度。
  2. 项目构建

    • 后端使用Spring Boot作为框架,集成Lucene进行全文索引和搜索。
    • 使用Apache Tika解析不同类型的文件内容。
    • 前端使用Vue.js实现用户界面,包括文件上传、搜索框和结果展示。
  3. 代码边界

    • 后端负责文件解析、索引构建和搜索逻辑。
    • 前端负责用户交互和结果显示。
  4. 结果展示

    • 搜索结果显示文件名、摘要信息以及匹配度。
    • 支持分页显示搜索结果。

项目结构

shop-api/
├── src/
│   ├── main/
│   │   ├── java/
│   │   │   └── com/example/shop/
│   │   │       ├── controller/
│   │   │       │   └── FileSearchController.java
│   │   │       ├── service/
│   │   │       │   ├── FileService.java
│   │   │       │   └── SearchService.java
│   │   │       ├── model/
│   │   │       │   └── SearchResult.java
│   │   │       └── config/
│   │   │           └── LuceneConfig.java
│   │   └── resources/
│   │       └── application.properties
└── pom.xml

后端代码实现

1. Lucene配置类
package com.example.shop.config;

import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.nio.file.Paths;

@Configuration
public class LuceneConfig {

    private static final String INDEX_DIR = "lucene-index";

    @Bean
    public Directory directory() throws Exception {
        return FSDirectory.open(Paths.get(INDEX_DIR));
    }

    @Bean
    public IndexWriter indexWriter(Directory directory) throws Exception {
        IndexWriterConfig config = new IndexWriterConfig(new StandardAnalyzer());
        return new IndexWriter(directory, config);
    }

    @Bean
    public DirectoryReader directoryReader(Directory directory) throws Exception {
        return DirectoryReader.open(directory);
    }
}

2. 文件服务类
package com.example.shop.service;

import org.apache.tika.Tika;
import org.apache.tika.exception.TikaException;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import org.xml.sax.SAXException;

import java.io.IOException;

@Service
public class FileService {

    private final Tika tika = new Tika();

    /**
     * 解析文件内容
     * @param file 上传的文件
     * @return 文件内容
     */
    public String parseFile(MultipartFile file) throws IOException, TikaException, SAXException {
        return tika.parseToString(file.getInputStream());
    }
}

3. 搜索服务类
package com.example.shop.service;

import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.TextField;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.queryparser.classic.ParseException;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopDocs;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

@Service
public class SearchService {

    @Autowired
    private IndexWriter indexWriter;

    @Autowired
    private DirectoryReader directoryReader;

    /**
     * 添加文件到索引
     * @param fileName 文件名
     * @param content 文件内容
     */
    public void addFileToIndex(String fileName, String content) throws IOException {
        Document doc = new Document();
        doc.add(new TextField("fileName", fileName, Field.Store.YES));
        doc.add(new TextField("content", content, Field.Store.YES));
        indexWriter.addDocument(doc);
        indexWriter.commit();
    }

    /**
     * 搜索文件
     * @param keyword 关键词
     * @return 搜索结果列表
     */
    public List<SearchResult> searchFiles(String keyword) throws IOException, ParseException {
        List<SearchResult> results = new ArrayList<>();
        IndexSearcher searcher = new IndexSearcher(directoryReader);
        Query query = new QueryParser("content", new StandardAnalyzer()).parse(keyword);
        TopDocs topDocs = searcher.search(query, 10);

        for (ScoreDoc scoreDoc : topDocs.scoreDocs) {
            Document doc = searcher.doc(scoreDoc.doc);
            SearchResult result = new SearchResult();
            result.setFileName(doc.get("fileName"));
            result.setContent(doc.get("content").substring(0, Math.min(100, doc.get("content").length())));
            result.setScore(scoreDoc.score);
            results.add(result);
        }

        return results;
    }
}

4. 搜索结果模型
package com.example.shop.model;

public class SearchResult {

    private String fileName;
    private String content;
    private float score;

    // Getters and Setters
    public String getFileName() {
        return fileName;
    }

    public void setFileName(String fileName) {
        this.fileName = fileName;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public float getScore() {
        return score;
    }

    public void setScore(float score) {
        this.score = score;
    }
}

5. 控制器类
package com.example.shop.controller;

import com.example.shop.model.SearchResult;
import com.example.shop.service.FileService;
import com.example.shop.service.SearchService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.List;

@RestController
@RequestMapping("/api/file")
public class FileSearchController {

    @Autowired
    private FileService fileService;

    @Autowired
    private SearchService searchService;

    /**
     * 上传文件并添加到索引
     */
    @PostMapping("/upload")
    public String uploadFile(@RequestParam("file") MultipartFile file) {
        try {
            String content = fileService.parseFile(file);
            searchService.addFileToIndex(file.getOriginalFilename(), content);
            return "File uploaded and indexed successfully.";
        } catch (Exception e) {
            return "Error uploading file: " + e.getMessage();
        }
    }

    /**
     * 搜索文件
     */
    @GetMapping("/search")
    public List<SearchResult> searchFiles(@RequestParam("keyword") String keyword) {
        try {
            return searchService.searchFiles(keyword);
        } catch (Exception e) {
            throw new RuntimeException("Error searching files: " + e.getMessage());
        }
    }
}


前端代码实现

前端使用Vue.js实现,以下是关键部分:

1. 主页面
<template>
  <div id="app">
    <h1>文件检索系统</h1>
    <input type="file" @change="uploadFile" />
    <input type="text" v-model="keyword" placeholder="请输入关键词" />
    <button @click="searchFiles">搜索</button>
    <ul>
      <li v-for="result in searchResults" :key="result.fileName">
        <strong>{{ result.fileName }}</strong>
        <p>{{ result.content }}</p>
        <span>匹配度: {{ result.score.toFixed(2) }}</span>
      </li>
    </ul>
  </div>
</template>

<script>
export default {
  data() {
    return {
      keyword: "",
      searchResults: []
    };
  },
  methods: {
    uploadFile(event) {
      const file = event.target.files[0];
      const formData = new FormData();
      formData.append("file", file);
      fetch("/api/file/upload", {
        method: "POST",
        body: formData
      }).then(response => response.text()).then(data => alert(data));
    },
    searchFiles() {
      fetch(`/api/file/search?keyword=${this.keyword}`)
        .then(response => response.json())
        .then(data => (this.searchResults = data));
    }
  }
};
</script>


总结

功能模块描述
文件上传用户上传文件,后端解析文件内容并添加到Lucene索引。
文件搜索用户输入关键词,后端返回匹配的文件列表,包含文件名、摘要和匹配度。
前端界面使用Vue.js实现文件上传和搜索结果展示。
技术栈Spring Boot + Lucene + Tika + Vue.js

以上代码实现了文件检索的核心功能,可以根据需求进一步优化和扩展。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱的叹息

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值