lucene7使用方法

首先添加依赖

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.nqwl</groupId>
  <artifactId>lucene</artifactId>
  <version>0.0.1-SNAPSHOT</version>

  <name>lucene</name>
  <!-- FIXME change it to the project's website -->
  <url>http://www.example.com</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <lunece.version>7.6.0</lunece.version>
  </properties> 
  <dependencies>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
    </dependency>
    <!-- lucene核心库 -->
    <dependency>
        <groupId>org.apache.lucene</groupId>
        <artifactId>lucene-core</artifactId>
        <version>${lunece.version}</version>
    </dependency>
    <!-- Lucene的查询解析器 -->
    <dependency>
        <groupId>org.apache.lucene</groupId>
        <artifactId>lucene-queryparser</artifactId>
        <version>${lunece.version}</version>
    </dependency>
    <!-- lucene的默认分词器库 -->
    <dependency>
        <groupId>org.apache.lucene</groupId>
        <artifactId>lucene-analyzers-common</artifactId>
        <version>${lunece.version}</version>
    </dependency>
    <!-- lucene的高亮显示 -->
    <dependency>
        <groupId>org.apache.lucene</groupId>
        <artifactId>lucene-highlighter</artifactId>
        <version>${lunece.version}</version>
    </dependency>
    <!-- 第三方分词器 google开发 中文分词更专业-->
    <!-- https://mvnrepository.com/artifact/com.github.magese/ik-analyzer -->
	<dependency>
	    <groupId>com.github.magese</groupId>
	    <artifactId>ik-analyzer</artifactId>
	    <version>7.6.0</version>
	</dependency>
  </dependencies>


  <build>
    <!-- jar名称 -->
    <finalName>netty_client</finalName>
    <!-- 使用shade打包 可以把第三方依赖包都打包进jar 防止确实依赖报错 -->
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId> maven-shade-plugin</artifactId>
                <version>2.3</version>
                <configuration>
                    <skipTests>true</skipTests>
                </configuration>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                        <configuration>
                            <transformers>
                                <transformer
                                    implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                                    <mainClass>com.nqwl.lucene.App</mainClass>  <!--这里运行类! -->
                                </transformer>
                            </transformers>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
  </build>
</project>

使用方法

package com.nqwl.lucene;

import static org.junit.Assert.assertTrue;

import java.io.File;
import java.io.IOException;
import java.io.StringReader;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.Field.Store;
import org.apache.lucene.document.LongPoint;
import org.apache.lucene.document.NumericDocValuesField;
import org.apache.lucene.document.StoredField;
import org.apache.lucene.document.StringField;
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.QueryParser;
import org.apache.lucene.search.BooleanClause.Occur;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.BoostQuery;
import org.apache.lucene.search.FuzzyQuery;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.MatchAllDocsQuery;
import org.apache.lucene.search.PhraseQuery;
import org.apache.lucene.search.PhraseQuery.Builder;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.Sort;
import org.apache.lucene.search.SortField;
import org.apache.lucene.search.SortField.Type;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.search.WildcardQuery;
import org.apache.lucene.search.highlight.Formatter;
import org.apache.lucene.search.highlight.Fragmenter;
import org.apache.lucene.search.highlight.Highlighter;
import org.apache.lucene.search.highlight.QueryScorer;
import org.apache.lucene.search.highlight.SimpleHTMLFormatter;
import org.apache.lucene.search.highlight.SimpleSpanFragmenter;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;
import org.junit.Ignore;
import org.junit.Test;
import org.wltea.analyzer.lucene.IKAnalyzer;


/**
 * Unit test for simple App.
 */
public class AppTest 
{
    /**
     * Ignore 不运行测试
     */
	@Ignore 
    public void shouldAnswerWithTrue()
    {
        assertTrue( true );
    }
    
	@Ignore
    // 创建索引
    public void testCreate() throws Exception{
        //1 创建文档对象
        Document document = new Document();
        // 创建并添加字段信息。参数:字段的名称、字段的值、是否存储,这里选Store.YES代表存储到文档列表。Store.NO代表不存储
        document.add(new StringField("id", "7", Field.Store.YES));
        // 这里我们title字段需要用TextField,即创建索引又会被分词。StringField会创建索引,但是不会被分词
        document.add(new TextField("title", "即创建索引又会被分词。StringField会创建索引,但是不会被分词", Field.Store.YES));
        
        //Lucene不直接支持数值(以及范围)的搜索 也就是说 数值存不到索引里 
        /**
         * 	新版本中使用了Int/Long/DoublePoint来表示数值型字段,但是默认不存储,不排序,也不支持加权
         *	创建索引加权值在6.6版本后就已经废除了,并给了搜索时设置的新query,这个后面查询时再说
         *	 如果存储需要用StoredField写相同的字段,排序还要再使用NumericDocValuesField写相同的排序,
         *	 如下的fileSize,添加long值索引,存储并添加排序支持
         *	注意: 如果要进行排序 需要添加两个以上文档进行排序 否则查询是报错
         */
        //创建数值字段
        document.add(new LongPoint("size", 50));
        //保存
        document.add(new StoredField("size", 50));
        //同时添加排序支持
        document.add(new NumericDocValuesField("size", 50));
        //StoredField 字段 只存储 不建索引 用于存储链接之类的数据
        // document.add(new StoredField("url", "www.yes58.cn"));
        //2 索引目录类,指定索引在硬盘中的位置 FSDirectory:文件系统目录,会把索引库指向本地磁盘。RAMDirectory:内存目录,会把索引库保存在内存
        Directory directory = FSDirectory.open(Paths.get("F:\\Java\\lucene-index"));
        //3 创建分词器对象 StandardAnalyzer 分词器 中文一个单词 是一个term 
        //Analyzer analyzer = new StandardAnalyzer();
        //CJKAnalyzer 分词器是针对东亚文字的分析器
        //IKAnalyzer google开源项目 一般中文分词都用这个
        Analyzer analyzer = new IKAnalyzer();
        //4 索引写出工具的配置对象
        IndexWriterConfig conf = new IndexWriterConfig(analyzer);
        //5 创建索引的写出工具类。参数:索引的目录和配置信息
        IndexWriter indexWriter = new IndexWriter(directory, conf);

        //6 把文档交给IndexWriter
        indexWriter.addDocument(document);
        //7 提交
        indexWriter.commit();
        //8 关闭
        indexWriter.close();
    }
    
 // 批量创建索引
	@Ignore
    public void testCreate2() throws Exception{
        // 创建文档的集合
        Collection<Document> docs = new ArrayList<>();
        // 创建文档对象
        Document document1 = new Document();
        document1.add(new StringField("id", "1", Field.Store.YES));
        document1.add(new TextField("title", "谷歌地图之父跳槽facebook", Field.Store.YES));
        document1.add(new LongPoint("size", 5));
        document1.add(new StoredField("size", 5));
        document1.add(new NumericDocValuesField("size", 5));
        docs.add(document1);
        // 创建文档对象
        Document document2 = new Document();
        document2.add(new StringField("id", "2", Field.Store.YES));
        document2.add(new TextField("title", "谷歌地图之父加盟FaceBook", Field.Store.YES));
        document2.add(new LongPoint("size", 1));
        document2.add(new StoredField("size", 1));
        document2.add(new NumericDocValuesField("size", 1));
        docs.add(document2);
        // 创建文档对象
        Document document3 = new Document();
        document3.add(new StringField("id", "3", Field.Store.YES));
        document3.add(new TextField("title", "谷歌地图创始人拉斯离开谷歌加盟Facebook", Field.Store.YES));
        document3.add(new LongPoint("size", 2));
        document3.add(new StoredField("size", 2));
        document3.add(new NumericDocValuesField("size", 2));
        docs.add(document3);
        // 创建文档对象
        Document document4 = new Document();
        document4.add(new StringField("id", "4", Field.Store.YES));
        document4.add(new TextField("title", "谷歌地图之父跳槽Facebook与Wave项目取消有关", Field.Store.YES));
        document4.add(new LongPoint("size", 3));
        document4.add(new StoredField("size", 3));
        document4.add(new NumericDocValuesField("size", 3));
        docs.add(document4);
        // 创建文档对象
        Document document5 = new Document();
        document5.add(new StringField("id", "5", Field.Store.YES));
        document5.add(new TextField("title", "谷歌地图之父拉斯加盟社交网站Facebook", Field.Store.YES));
        document5.add(new LongPoint("size", 4));
        document5.add(new StoredField("size", 4));
        document5.add(new NumericDocValuesField("size", 4));
        docs.add(document5);

        // 索引目录类,指定索引在硬盘中的位置
        Directory directory = FSDirectory.open(Paths.get("F:\\Java\\lucene-index"));
        // 引入IK分词器
        Analyzer analyzer = new IKAnalyzer();
        // 索引写出工具的配置对象
        IndexWriterConfig conf = new IndexWriterConfig(analyzer);
        // 设置打开方式:OpenMode.APPEND 会在索引库的基础上追加新索引。OpenMode.CREATE会先清空原来数据,再提交新的索引
        conf.setOpenMode(IndexWriterConfig.OpenMode.CREATE);

        // 创建索引的写出工具类。参数:索引的目录和配置信息
        IndexWriter indexWriter = new IndexWriter(directory, conf);
        // 把文档集合交给IndexWriter
        indexWriter.addDocuments(docs);
        // 提交
        indexWriter.commit();
        // 关闭
        indexWriter.close();
    }

    // 查询索引数据
	@Ignore
    public void testSearch() throws Exception {
        // 索引目录对象
        Directory directory = FSDirectory.open(Paths.get("F:\\Java\\lucene-index"));
        // 索引读取工具
        IndexReader reader = DirectoryReader.open(directory);
        // 索引搜索工具
        IndexSearcher searcher = new IndexSearcher(reader);

        // 创建查询解析器,两个参数:默认要查询的字段的名称,分词器
        //QueryParser parser = new QueryParser("title", new IKAnalyzer());
        
        //创建查询解析器 多字段查询
        MultiFieldQueryParser parser = new MultiFieldQueryParser(new String[]{"id", "title"}, new IKAnalyzer());
        // 创建查询对象
        Query query = parser.parse("1");

        // 搜索数据,两个参数:查询条件对象要查询的最大结果条数
        // 返回的结果是 按照匹配度排名得分前N名的文档信息(包含查询到的总条数信息、所有符合条件的文档的编号信息)。
        TopDocs topDocs = searcher.search(query, 10);
        // 获取总条数
        System.out.println("本次搜索共找到" + topDocs.totalHits + "条数据");
        // 获取得分文档对象(ScoreDoc)数组.SocreDoc中包含:文档的编号、文档的得分
        ScoreDoc[] scoreDocs = topDocs.scoreDocs;
        for (ScoreDoc scoreDoc : scoreDocs) {
            // 取出文档编号
            int docID = scoreDoc.doc;
            // 根据编号去找文档
            Document doc = reader.document(docID);
            System.out.println("id: " + doc.get("id"));
            System.out.println("title: " + doc.get("title"));
            // 取出文档得分
            System.out.println("得分: " + scoreDoc.score);
        }
    }
    
    //公用的搜索方法
    public void search(Query query) throws Exception {
        // 索引目录对象
        Directory directory = FSDirectory.open(Paths.get("F:\\Java\\lucene-index"));
        // 索引读取工具
        IndexReader reader = DirectoryReader.open(directory);
        // 索引搜索工具
        IndexSearcher searcher = new IndexSearcher(reader);

        // 搜索数据,两个参数:查询条件对象要查询的最大结果条数
        // 返回的结果是 按照匹配度排名得分前N名的文档信息(包含查询到的总条数信息、所有符合条件的文档的编号信息)。
        TopDocs topDocs = searcher.search(query, 10);
        // 获取总条数
        System.out.println("本次搜索共找到" + topDocs.totalHits + "条数据");
        // 获取得分文档对象(ScoreDoc)数组.SocreDoc中包含:文档的编号、文档的得分
        ScoreDoc[] scoreDocs = topDocs.scoreDocs;

        for (ScoreDoc scoreDoc : scoreDocs) {
            // 取出文档编号
            int docID = scoreDoc.doc;
            // 根据编号去找文档
            Document doc = reader.document(docID);
            System.out.println("id: " + doc.get("id"));
            System.out.println("title: " + doc.get("title"));
            System.out.println("size: " + doc.get("size"));
            // 取出文档得分
            System.out.println("得分: " + scoreDoc.score);
        }
    }

    //TermQuery(词条查询)
    /*
     * 	测试普通词条查询
     *	 注意:Term(词条)是搜索的最小单位,不可再分词。值必须是字符串!
     *	 场景:如果我们查询的字段不需要分词 就使用词条查询
     */
    @Ignore
    public void testTermQuery() throws Exception {
        // 创建词条查询对象
        Query query = new TermQuery(new Term("title", "谷歌地图"));
        search(query);
    }

    //WildcardQuery(通配符查询)
    /*
     * 	测试通配符查询
     * 	? 可以代表任意一个字符
     * 	* 可以任意多个任意字符
     */
    @Ignore
    public void testWildCardQuery() throws Exception {
        // 创建查询对象
        Query query = new WildcardQuery(new Term("title", "*谷*"));
        search(query);
    }

    /*
     *	 测试模糊查询
     */
    @Ignore
    public void testFuzzyQuery() throws Exception {
        // 创建模糊查询对象:允许用户输错。但是要求错误的最大编辑距离不能超过2
        // 编辑距离:一个单词到另一个单词最少要修改的次数 facebool --> facebook 需要编辑1次,编辑距离就是1
    	//    Query query = new FuzzyQuery(new Term("title","fscevool"));
        // 可以手动指定编辑距离,但是参数必须在0~2之间
        Query query = new FuzzyQuery(new Term("title","fecebool"),2);
        search(query);
    }

    /* 测试:修改索引
     * 	注意:
     * 	A:Lucene修改功能底层会先删除,再把新的文档添加。
     * 	B:修改功能会根据Term进行匹配,所有匹配到的都会被删除。这样不好
     * 	C:因此,一般我们修改时,都会根据一个唯一不重复字段进行匹配修改。例如ID
     * 	D:但是词条搜索,要求ID必须是字符串。如果不是,这个方法就不能用。
     * 	如果ID是数值类型,我们不能直接去修改。可以先手动删除deleteDocuments(数值范围查询锁定ID),再添加。
     */
	@Ignore
	public void testUpdate() throws Exception{
	    // 创建目录对象
	    Directory directory = FSDirectory.open(Paths.get("F:\\Java\\lucene-index"));
	    // 创建配置对象
	    IndexWriterConfig conf = new IndexWriterConfig(new IKAnalyzer());
	    // 创建索引写出工具
	    IndexWriter writer = new IndexWriter(directory, conf);
	
	    // 创建新的文档数据
	    Document doc = new Document();
	    doc.add(new StringField("id","1",Store.YES));
	    doc.add(new TextField("title","谷歌地图之父跳槽facebook-UPDATE",Store.YES));
	    /* 修改索引。参数:
	         * 	词条:根据这个词条匹配到的所有文档都会被修改
	         * 	文档信息:要修改的新的文档数据
	         */
	    writer.updateDocument(new Term("id","1"), doc);
	    // 提交
	    writer.commit();
	    // 关闭
	    writer.close();
	}

	/*
	 * 演示:删除索引
	 * 注意:
	 * 	一般,为了进行精确删除,我们会根据唯一字段来删除。比如ID
	 * 	如果是用Term删除,要求ID也必须是字符串类型!
	 */
	@Ignore
	public void testDelete() throws Exception {
	// 创建目录对象
	Directory directory = FSDirectory.open(Paths.get("F:\\Java\\lucene-index"));
	// 创建配置对象
	IndexWriterConfig conf = new IndexWriterConfig(new IKAnalyzer());
	// 创建索引写出工具
	IndexWriter writer = new IndexWriter(directory, conf);
	
	// 根据词条进行删除
	//		writer.deleteDocuments(new Term("id", "1"));
	
	// 根据query对象删除,如果ID是数值类型,那么我们可以用数值范围查询锁定一个具体的ID
	//		Query query = NumericRangeQuery.newLongRange("id", 2L, 2L, true, true);
	//		writer.deleteDocuments(query);
	
	// 删除所有
	writer.deleteAll();
	// 提交
	writer.commit();
	// 关闭
	writer.close();
	}

	
	//高亮显示
	//1 创建目录 对象
    //2 创建索引读取工具

	//3 创建索引搜索工具

	//4 创建查询解析器

	//5 创建查询对象

	//6 创建格式化器

	//7 创建查询分数工具

	//8 准备高亮工具

	//9 搜索

	//10 获取结果

	//11 用高亮工具处理普通的查询结果
	// 高亮显示
    @Ignore
    public void testHighlighter() throws Exception {
        // 目录对象
        Directory directory = FSDirectory.open(Paths.get("F:\\Java\\lucene-index"));
        // 创建读取工具
        IndexReader reader = DirectoryReader.open(directory);
        // 创建搜索工具
        IndexSearcher searcher = new IndexSearcher(reader);

        QueryParser parser = new QueryParser("title", new IKAnalyzer());
        Query query = parser.parse("谷歌地图");

        // 格式化器
        Formatter formatter = new SimpleHTMLFormatter("<em>", "</em>");
        QueryScorer scorer = new QueryScorer(query);
        // 准备高亮工具
        Highlighter highlighter = new Highlighter(formatter, scorer);
        // 搜索
        TopDocs topDocs = searcher.search(query, 10);
        System.out.println("本次搜索共" + topDocs.totalHits + "条数据");

        ScoreDoc[] scoreDocs = topDocs.scoreDocs;
        for (ScoreDoc scoreDoc : scoreDocs) {
            // 获取文档编号
            int docID = scoreDoc.doc;
            Document doc = reader.document(docID);
            System.out.println("id: " + doc.get("id"));

            String title = doc.get("title");
            // 用高亮工具处理普通的查询结果,参数:分词器,要高亮的字段的名称,高亮字段的原始值
            String hTitle = highlighter.getBestFragment(new IKAnalyzer(), "title", title);

            System.out.println("title: " + hTitle);
            // 获取文档的得分
            System.out.println("得分:" + scoreDoc.score);
        }

    }

    // 排序
    @Ignore
    public void testSortQuery() throws Exception {
        // 目录对象
        Directory directory = FSDirectory.open(Paths.get("F:\\Java\\lucene-index"));
        // 创建读取工具
        IndexReader reader = DirectoryReader.open(directory);
        // 创建搜索工具
        IndexSearcher searcher = new IndexSearcher(reader);

        QueryParser parser = new QueryParser("title", new IKAnalyzer());
        Query query = parser.parse("谷歌地图");

        // 创建排序对象,需要排序字段SortField,参数:字段的名称、字段的类型、是否反转如果是false,升序。true降序
        Sort sort = new Sort(new SortField("size", Type.LONG, true));
        // 搜索
        TopDocs topDocs = searcher.search(query, 10, sort);
        System.out.println("本次搜索共" + topDocs.totalHits + "条数据");

        ScoreDoc[] scoreDocs = topDocs.scoreDocs;
        for (ScoreDoc scoreDoc : scoreDocs) {
            // 获取文档编号
            int docID = scoreDoc.doc;
            Document doc = reader.document(docID);
            System.out.println("id: " + doc.get("id"));
            System.out.println("title: " + doc.get("title"));
            System.out.println("size: " + doc.get("size"));
        }
    }
    
    //排序加高亮显示
    @Ignore
    public void printResult() throws Exception{
    	// 目录对象
        Directory directory = FSDirectory.open(Paths.get("F:\\Java\\lucene-index"));
        // 创建读取工具
        IndexReader reader = DirectoryReader.open(directory);
        // 创建搜索工具
        IndexSearcher searcher = new IndexSearcher(reader);
        //使用排序
        Sort sort  =new Sort();
        SortField f  =new SortField("size",Type.LONG,true); // 按照fileSize字段排序,true表示降序
        sort.setSort(f);
        // 多个条件排序
        // Sort sort = new Sort();
        // SortField f1 = new SortField("createdate", SortField.DOC, true);
        // SortField f2 = new SortField("bookname", SortFiedl.INT, false);
        // sort.setSort(new SortField[] { f1, f2 });
        QueryParser parser = new QueryParser("title", new IKAnalyzer());
        Query query = parser.parse("谷歌");
        //高亮显示start 
        //算分 
        QueryScorer scorer=new QueryScorer(query); 
        //显示得分高的片段 
        Fragmenter fragmenter=new SimpleSpanFragmenter(scorer); 
        //设置标签内部关键字的颜色 
        //第一个参数:标签的前半部分;第二个参数:标签的后半部分。 
        SimpleHTMLFormatter simpleHTMLFormatter=new SimpleHTMLFormatter("<b><font color='red'>","</font></b>");        
        //第一个参数是对查到的结果进行实例化;第二个是片段得分(显示得分高的片段,即摘要) 
        Highlighter highlighter=new Highlighter(simpleHTMLFormatter, scorer); 
        //设置片段 
        highlighter.setTextFragmenter(fragmenter); 
        //高亮显示end
       TopDocs topDocs = searcher.search(query, 10,sort);
       ScoreDoc[] scoreDocs = topDocs.scoreDocs;//文档id数组
       for (ScoreDoc scoreDoc : scoreDocs) {
           //根据id获取文档
           Document doc = searcher.doc(scoreDoc.doc);
           String name = doc.get("title");
           if(name!=null){
               //把全部得分高的摘要给显示出来 
               //第一个参数是对哪个参数进行设置;第二个是以流的方式读入          
               TokenStream tokenStream=new IKAnalyzer().tokenStream("title", new StringReader(name));
               //获取最高的片段 
               System.out.println("高亮文档名: "+highlighter.getBestFragment(tokenStream, name));              
           }
           //获取结果,没有存储的是null,比如内容
           System.out.println("文档名: "+doc.get("id"));
           System.out.println("文档路径: "+doc.get("title"));
           System.out.println("顺序: "+doc.get("size"));
           System.out.println("-------------------");
       }       
   }
    
    /*
	 * 测试:数值范围查询
	 * 注意:数值范围查询,可以用来对非String类型的ID进行精确的查找
	 */
    @Ignore
    public void testSelect01() throws Exception{
        //数字范围查询, 两边都是闭区间   43< index  <103
        //新版本中数值都使用Point进行查询,原理的Numic被废弃
        //Query query=LongPoint.newRangeQuery("fileSize", 43L, 103L);
        //数值精确匹配,只会查找参数里的数值索引   index  in   param
        List<Long> list=new ArrayList<Long>();
        list.add(1L);
        list.add(3L);
        Query query2=LongPoint.newSetQuery("size", 2,5);//不定参数
        Query query1=LongPoint.newSetQuery("size", list); //集合参数
        search(query2);
        System.out.println("------------");
        search(query1);
    }
    
    /**
     * BooleanQuery也是实际开发过程中经常使用的一种Query。
     * 它其实是一个组合的Query,在使用时可以把各种Query对象添加进去并标明它们之间的逻辑关系。
     * 所有的Query都可以通过booleanQUery组合起来
     * BooleanQuery本身来讲是一个布尔子句的容器,它提供了专门的API方法往其中添加子句,
     * 并标明它们之间的关系
     */
    @Ignore
    public void testSelect03() throws Exception{
        //组合条件
        //Query query1=new TermQuery(new Term("title","谷歌"));
        //Query query2=new TermQuery(new Term("title","拉斯"));
    	
    	//跨字段合并
    	Query query1=new TermQuery(new Term("title","谷歌地图"));
        Query query2=new TermQuery(new Term("id","7"));
    	
        //相当于一个包装类,将 Query 设置 Boost 值 ,然后包装起来。
        //再通过复合查询语句,可以突出 Query 的优先级
        BoostQuery query=new BoostQuery(query2, 2f);
        //创建BooleanQuery.Builder
        BooleanQuery.Builder  builder=new BooleanQuery.Builder();
        //添加逻辑
        /**
         *   1.MUST和MUST:取得两个查询子句的交集。  and
             2.MUST和MUST_NOT:表示查询结果中不能包含MUST_NOT所对应得查询子句的检索结果。
             3.SHOULD与MUST_NOT:连用时,功能同MUST和MUST_NOT。
             4.SHOULD与MUST连用时,结果为MUST子句的检索结果,但是SHOULD可影响排序。
             5.SHOULD与SHOULD:表示“或”关系,最终检索结果为所有检索子句的并集。
             6.MUST_NOT和MUST_NOT:无意义,检索无结果。
         */
        builder.add(query1, Occur.SHOULD);// 文件名不包含词语,但是内容必须包含姚振
        builder.add(query, Occur.SHOULD);
        //build query
        BooleanQuery  booleanQuery=builder.build();
        search(booleanQuery);
    }

    //查询所有
    @Ignore
    public void testSelect() throws Exception{        
        Query queryAll=new MatchAllDocsQuery();
        search(queryAll);
    }
    
    /**
     *  PhraseQuery,是指通过短语来检索,比如我想查“姚振 牛逼”这个短语,
     *  那么如果待匹配的document的指定项里包含了"姚振 牛逼"这个短语,
     *  这个document就算匹配成功。可如果待匹配的句子里包含的是“姚振 真他妈 牛逼”,
     *  那么就无法匹配成功了,如果也想让这个匹配,就需要设定slop,
     *  先给出slop的概念:slop是指两个项的位置之间允许的最大间隔距离
     */
    @Test
    public void test06() throws Exception{
        Builder build = new PhraseQuery.Builder();
        build.add(new Term("title","谷歌"));
        build.add(new Term("title","有关"));
        //设置slop,即最大相隔多远,即多少个文字的距离,
        build.setSlop(60);//表示如果这两个词语相隔60个字以下的位置就匹配
        PhraseQuery phraseQuery = build.build();
        search(phraseQuery);
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值