欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Lucene的条件查询

程序员文章站 2022-07-09 09:55:03
...

MainTest文件

因为没有做Lucene的util,比较冗杂

package lucene;

import java.io.File;

import java.io.IOException;
import java.nio.file.Paths;
import java.util.ArrayList;

import java.util.List;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.hunspell.Dictionary;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.FloatDocValuesField;
import org.apache.lucene.document.Field.Store;
import org.apache.lucene.document.FloatPoint;
import org.apache.lucene.document.StoredField;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.document.TextField;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.Term;
import org.apache.lucene.queryparser.classic.MultiFieldQueryParser;
import org.apache.lucene.queryparser.classic.ParseException;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.search.BooleanClause.Occur;
import org.junit.Test;

import com.seehope.lucene.dao.BookDao;
import com.seehope.lucene.pojo.Book;
public class MainTest {

    //···生成lucene索引库

    public void test() {
        BookDao BookDao=new BookDao();
        List<Book> books=BookDao.queryAllBook();
        List<Document> documents=new ArrayList<Document>();

        Document document=null;
        int i=0;
        for (Book book : books) {
            document=new Document();

            /**
             *  是否分词
             *  是否建立索引(该域有没有可能成为查询条件)有可能成为查询条件的类建立索引
             *  是否储存是否要将file的value存在文件中。如果需要直接从lucene中得到数据的字段,才需要储存
             */
            //id不需要分词,要索引和储存
            Field id=new StoredField("id",book.getId().toString());
            //需要分词,需要索引,需要储存
            Field name=new TextField("name",book.getName(),Store.YES);
            //lucene 对数值类型有特殊的分词要求  要储存 要索引
            document.add(new FloatPoint("price", book.getPrice()));
            document.add(new FloatDocValuesField("prive", book.getPrice()));//储存
            document.add(new StoredField("prive", book.getPrice()));//索引
            //不分词,不索引,要储存
            Field pic=new StoredField("pic",book.getPic());
            //分词,索引,不储存
            Field description=new TextField("description",book.getDescription(),Store.NO);

            document.add(new TextField("index",""+(++i)+"",Store.YES));

            document.add(id);
            document.add(name);
            document.add(pic);
            document.add(description);
            documents.add(document);

            Analyzer analyzer=new StandardAnalyzer();
            try {
                Directory dictionary=FSDirectory.open(Paths.get(new File("lucene").getAbsolutePath()));
                IndexWriterConfig config=new IndexWriterConfig(analyzer);
                IndexWriter indexWriter=new IndexWriter(dictionary, config);
                for (Document doc : documents) {
                    indexWriter.addDocument(doc);
                }
                indexWriter.close();
            } catch (Exception e) {
                // TODO: handle exception
            }
        }
    }
    //删除 ByTerm
    public void deleteDocumentByTerm() throws IOException {
        Analyzer analyzer=new StandardAnalyzer();
        Directory dictionary=FSDirectory.open(Paths.get(new File("lucene").getAbsolutePath()));
        IndexWriterConfig config=new IndexWriterConfig(analyzer);
        IndexWriter indexWriter=new IndexWriter(dictionary, config);

        System.out.println("有: "+indexWriter.deleteDocuments
                (new Term("index","1"))+"条记录被删除");
        indexWriter.close();
    }
    //更新 比较low··它是先删除再加进去
    public void updateDocumentByTerm() throws IOException {
        Analyzer analyzer=new StandardAnalyzer();
        Directory dictionary=FSDirectory.open(Paths.get(new File("lucene").getAbsolutePath()));
        IndexWriterConfig config=new IndexWriterConfig(analyzer);
        IndexWriter indexWriter=new IndexWriter(dictionary, config);

        Document document=new Document();
        document.add(new TextField("index", "1",Store.YES));
        System.out.println("有: "+indexWriter.updateDocument
                (new Term("index","2"),document)+"条记录被更新");
        indexWriter.close();
    }
    //查询

    public void showSearch() throws IOException, ParseException {
        Analyzer analyzer=new StandardAnalyzer();
        Directory directory=FSDirectory.open(Paths.get(new File("lucene").getAbsolutePath()));
        QueryParser parser=new QueryParser("description", analyzer);
        Query query=parser.parse("description:java AND lucene");
        IndexReader indexReader=DirectoryReader.open(directory);
        IndexSearcher indexSearcher=new IndexSearcher(indexReader);
        TopDocs topDoc=indexSearcher.search(query, 10);
        ScoreDoc[] scoreDocs=topDoc.scoreDocs;
        System.out.println("当前查询语句中 击中了多少条记录:"+topDoc.totalHits);
        for (ScoreDoc scoDoc : scoreDocs) {
            int docid=scoDoc.doc;
            Document document=indexSearcher.doc(docid);
            System.out.println("文档id:"+docid);
            System.out.println(document.get("id"));
            System.out.println(document.get("name"));
            System.out.println(document.get("price"));
            System.out.println(document.get("pic"));
            System.out.println(document.get("description"));
        }
    }

    //对索引进行查询
    public void doSearch(Query query) throws IOException {
        Analyzer analyzer=new StandardAnalyzer();
        Directory directory=FSDirectory.open(Paths.get(new File("lucene").getAbsolutePath()));
        IndexReader indexReader=DirectoryReader.open(directory);
        IndexSearcher indexSearcher=new IndexSearcher(indexReader);
        TopDocs topDoc=indexSearcher.search(query, 10);
        ScoreDoc[] scoreDocs=topDoc.scoreDocs;
        System.out.println("当前查询语句中 击中了多少条记录:"+topDoc.totalHits);
        for (ScoreDoc scoDoc : scoreDocs) {
            int docid=scoDoc.doc;
            Document document=indexSearcher.doc(docid);
            System.out.println("文档id:"+docid);
            System.out.println(document.get("id"));
            System.out.println(document.get("name"));
            System.out.println(document.get("price"));
            System.out.println(document.get("pic"));
            System.out.println(document.get("description"));
        }
    }

    //靠term查询   分词查询

    public void queryBocumentByTerm() throws IOException {
        Query query=new TermQuery(new Term("id","3"));
        System.out.println(query);
        doSearch(query);
    }

    //靠number 查询      price的【10100)区间
    //根据FloatPoint.nextDown决定是不是开或者闭区间
    public void queryDocumentByNumberQuery() throws IOException {
        Query query=FloatPoint.newRangeQuery("price", 10f, FloatPoint.nextDown(100f));
        System.out.println(query);
        doSearch(query);
    }

    //根据是否满足多条件查询   SHOULD或(多条件有一个符合就行)     MUST和(多条件必须符合)
    public void queryDocumentByBooleanQuery() throws IOException {
        Query query1=FloatPoint.newRangeQuery("price", 10f, FloatPoint.nextDown(100f));
        Query query2=new TermQuery(new Term("id","3"));
        BooleanQuery query=new BooleanQuery.Builder().add(query1,Occur.MUST)
                .add(query2,Occur.MUST).build();
        doSearch(query);
    }

    //符合两个域名同一个关键字
    @Test
    public void multiFeildQueryParser() throws IOException, ParseException {
        String[] fields= {"name","discription"};
        QueryParser parser=new MultiFieldQueryParser(fields, new StandardAnalyzer());
        Query query=parser.parse("java");
        System.out.println(query);
        doSearch(query);
    }
    /**
     *  感觉有点万能
     *  1.域名:搜索关键字
     *  content:java  (域名content  :  关键字java)
     *  2.范围查询
     *  域名:【最小值   TO  最大值】  比如说     size:[1 TO 100]
     *  3.组合条件查询
     *  -price:[10.0 TO 99.99999] name:spring   必须不符合第一个条件
     *  +price:[10.0 TO 99.99999] +name:spring  必须符合第两个条件
     *  price:[10.0 TO 99.99999] name:spring    符合第一个条件或者符合第二个条件
     *  4.两个域名同一个关键字
     *  name:java discription:java  (或的意思)
     * @throws ParseException 
     * @throws IOException 
     *  
     */

    public void queryDocumentByQueryParser() throws ParseException, IOException {
        QueryParser parser=new QueryParser("price",new StandardAnalyzer());
        Query query=parser.parse("+price:[10.0 TO 99.99999] +name:spring");
        System.out.println(query);
        doSearch(query);
    }


}

Lucene的条件查询
BookDao

package com.seehope.lucene.dao;


import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;


import com.seehope.lucene.pojo.Book;

public class BookDao {

    public List<Book> queryAllBook(){
        try {
            Class.forName("com.mysql.jdbc.Driver");
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        List<Book> books=new ArrayList<Book>();
        String sql="select * from book";
        Connection connection;
        try {
            connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/lecene", "root", "123456");
            PreparedStatement preparedStatement=connection.prepareStatement(sql);
            ResultSet set=preparedStatement.executeQuery();

            while(set.next()) {
                Book book=new Book(set.getInt("id"),set.getString("name"),set.getFloat("price"),set.getString("pic"),set.getString("description"));

                books.add(book);
            }


        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }



        return books;

    }
}

Book

package com.seehope.lucene.pojo;

import java.io.Serializable;

import org.apache.lucene.document.IntRange;

public class Book implements Serializable{

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    private Integer id;
    private String name;
    private Float price;
    private String pic;
    private String description;
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Float getPrice() {
        return price;
    }
    public void setPrice(Float price) {
        this.price = price;
    }
    public String getPic() {
        return pic;
    }
    public void setPic(String pic) {
        this.pic = pic;
    }
    public String getDescription() {
        return description;
    }
    public void setDescription(String description) {
        this.description = description;
    }
    public static long getSerialversionuid() {
        return serialVersionUID;
    }
    @Override
    public String toString() {
        return "Book [id=" + id + ", name=" + name + ", price=" + price + ", pic=" + pic + ", description="
                + description + "]";
    }

    public Book(Integer id, String name, Float price, String pic, String description) {
        super();
        this.id = id;
        this.name = name;
        this.price = price;
        this.pic = pic;
        this.description = description;
    }
    public Book(String name, Float price, String pic, String description) {
        super();
        this.name = name;
        this.price = price;
        this.pic = pic;
        this.description = description;
    }
    public Book() {
        super();
    }


}

pom.xml的依赖(搭建环境)

<dependencies>
    <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.46</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/org.apache.lucene/lucene-core -->
    <dependency>
        <groupId>org.apache.lucene</groupId>
        <artifactId>lucene-core</artifactId>
        <version>7.4.0</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/org.apache.lucene/lucene-queryparser -->
    <dependency>
        <groupId>org.apache.lucene</groupId>
        <artifactId>lucene-queryparser</artifactId>
        <version>7.4.0</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.apache.lucene/lucene-analyzers-common -->
    <dependency>
        <groupId>org.apache.lucene</groupId>
        <artifactId>lucene-analyzers-common</artifactId>
        <version>7.4.0</version>
    </dependency>

  </dependencies>