Lucene&Solr(之二)-索引库CRUD、Solr的安装

Lucene索引库的维护

首先getIndexWriter
	private IndexWriter getIndexWriter() throws Exception {
		Directory directory = FSDirectory.open(new File("F:\\index"));
		IndexWriterConfig config = new IndexWriterConfig(Version.LATEST, new IKAnalyzer());
		// 创建indexWriter
		IndexWriter indexWriter = new IndexWriter(directory, config);
		return indexWriter;
	}

索引库的添加
	@Test
	// 索引库的添加
	public void addDocument() throws Exception {
		IndexWriter indexWriter = getIndexWriter();
		// 创建document对象
		Document document = new Document();
		Field name = new TextField("name", "apache.txt", Store.YES);
		name.setBoost(10.0f);	// 设置相关度
		document.add(name);
		document.add(new TextField("name1", "我是name1", Store.YES));
		document.add(new TextField("name2", "我是name2", Store.YES));
		document.add(new LongField("content", 1000l, Store.NO));
		// 添加document'到索引库
		indexWriter.addDocument(document);
		// 关闭
		indexWriter.close();
	}
索引库的删除
	@Test
	// 删除所有  注:慎用慎用!
	public void deleteAllDocument() throws Exception {
		IndexWriter indexWriter = getIndexWriter();
		
		indexWriter.deleteAll();
		indexWriter.commit();
		indexWriter.close();
	}

条件的删除
	@Test
	// 指定查询条件删除
	public void deleteDocumentByQuery() throws Exception {
		IndexWriter indexWriter = getIndexWriter();
		
		// 创建查询条件
		Query query = new TermQuery(new Term("name", "apache"));
		indexWriter.deleteDocuments(query);
		indexWriter.close();
	}


索引库的修改
	@Test
	// 修改索引库 原理:先删除再添加
	public void updateDocument() throws Exception {
		IndexWriter indexWriter = getIndexWriter();
		
		// 创建 document
		Document document = new Document();
		document.add(new TextField("name", "更新了的文档",Store.YES));
		document.add(new TextField("content", "这个文档被更新了",Store.YES));
		
		indexWriter.updateDocument(new Term("name", "apache"), document);
		indexWriter.close();
	}

Field域的属性

1、是否分析:是否要对域中的内容进行分词。
判断标准:是否要对域的内容进行分词。
2、是否索引:域中的内容是否要进行索引,如果不索引查询不到结果。
判断标准:是否要在域上进行查询。如果要查询就需要创建索引。
3、是否存储:是否把域的中的原始内容保存到磁盘。如果不存储域中是取不到结果的。

判断标准:是否要展示给用户看,或者业务逻辑中是否需要域的内容。

以此来进行field的子类的选择。( StringField、LongField、StoredField、TextField )




索引库的查询

对要搜索的信息创建Query对象,可通过两种方法创建查询对象。
首先抽取通用代码:
	private IndexSearcher getIndexSearcher() throws Exception {
		IndexReader indexReader = DirectoryReader.open(FSDirectory.open(new File("F:\\index")));
		IndexSearcher indexSearcher = new IndexSearcher(indexReader);
		return indexSearcher;
	}
	private void printResult(Query query) throws Exception {
		IndexSearcher indexSearcher = getIndexSearcher();
		TopDocs topDocs = indexSearcher.search(query, 10);
		System.out.println("查询的总记录数:" + topDocs.totalHits);
		for (ScoreDoc scoreDoc : topDocs.scoreDocs) {
			int id = scoreDoc.doc;
			Document document = indexSearcher.doc(id);
			// 取field的值
			System.out.println("==============================================================================");
			System.out.println(document.get("id"));
			System.out.println(document.get("name"));
			System.out.println("content:" + document.get("content"));
			System.out.println(document.get("path"));
			System.out.println(document.get("size"));
		}
		
		indexSearcher.getIndexReader().close();
	}


1、使用lucene提供的Query子类
使用TermQuery进行查询:
	@Test
	// 创建TermQuery查询
	public void testQueryTerm() throws Exception {
		Query query = new TermQuery(new Term("name", "apache"));
		System.out.println(query);	// name:name
		printResult(query);
	}
查询所有:MatchAllDocsQuery
	@Test
	// 查询所有
	public void testMatchAllDocsQuery() throws Exception {
		Query query = new MatchAllDocsQuery();
		System.out.println(query);	// *:*
		printResult(query);
	}
根据数值范围查询:NumericRangeQuery
	@Test
	// 数值范围查询
	public void testNumericRangeQuery() throws Exception {
		Query query = NumericRangeQuery.newLongRange("size", 0l, 3000l, true, true);
		System.out.println(query);	// size:[0 TO 3000]
		printResult(query);
	}

BooleanQuery:组合条件查询,可以指定多个查询条件:
	@Test
	// 多条件查询
	public void testBooleanQuery() throws Exception {
		BooleanQuery query = new BooleanQuery();
		// 设置 条件
		Query query1 = new TermQuery(new Term("name", "apache"));
		Query query2 = NumericRangeQuery.newLongRange("size", 0l, 3000l, true, false);
		// 组合
		query.add(query1, Occur.MUST);
		query.add(query2, Occur.MUST_NOT);
		
		System.out.println(query);	// +name:apache +size:[0 TO 3000}
		printResult(query);
	}
条件直接的关系:
Occur.MUST:条件必须满足,相当于AND
Occur.SHOULD:条件应该满足,相当于OR
Occur.MUST_NOT:条件必须不能满足,相当于NOT


2、使用QueryParse解析查询表达式
先导入queryparser的jar包:在lucene目录下的扩展包中
	@Test
	// 分析查询时,默认域的查询
	public void testQueryParser() throws Exception {
		// 参数1: 默认搜索的域   参数2:分析器
		QueryParser queryParser = new QueryParser("content", new IKAnalyzer());
		Query query = queryParser.parse("Lucene is a apache project");
		System.out.println(query);	// content:lucene content:apache content:project   is和a为停用词
		printResult(query);
	}
	@Test
	// 分析查询时,默认域的查询
	public void testQueryParser() throws Exception {
		// 参数1: 默认搜索的域   参数2:分析器
		QueryParser queryParser = new QueryParser("name", new IKAnalyzer());
		Query query = queryParser.parse("name:apache");
		System.out.println(query);	
		printResult(query);
	}


多个默认搜索域:
	@Test
	// 多个默认搜索域
	public void testMulTiFieldQuery() throws Exception {
		String[] fields = {"name","content"};
		MultiFieldQueryParser queryParser = new MultiFieldQueryParser(fields, new IKAnalyzer());
		Query query = queryParser.parse("Lucene is a apache project");
		System.out.println(query);	// (name:lucene content:lucene) (name:apache content:apache) (name:project content:project)
		printResult(query);
	}

Lucene的查询语法:

1、基本语法:域名:关键字
如:   name:apache
2、查询所有文档
*:*
3、范围查询语法:域名:[ 最小值 TO 最大值 ]
[ ]:包含边界值
{ }:不包含边界值
如:size:[ 0 TO 1000 ]
注:在lucene中范围查询只支持字符串类型,数值范围使用NumericRangeQuery。Solr中是支持的。

4、组合条件查询语法
+name:apache +size:[1000 TO 10000]+:相当于AND
name:apache size:[1000 TO 10000]没有前缀:相当于OR
-name:apache size:[1000 TO 10000]-:相当于NOT

第二种写法:
name:apache AND size:[1000 TO 10000]
name:apache OR size:[1000 TO 10000]
NOT name:apache size:[1000 TO 10000]


相关度排序

相关度排序是查询结果按照查询关键字的相关性进行排序。越相关的越靠前。

相关度打分:
1、计算词的(term)的权重
2、根据权重值,采用空间向量模型算法计算文档相关度得分。

影响term权重的两个因素:
Term Frequency(tf):
指term在文档中出现了多少次。tf越大说明越重要。

Document Frequency(df):
指有多少文档包含此term。df越大说明越不重要。

设置boost影响得分结果:
	@Test
	// 索引库的添加
	public void addDocument() throws Exception {
		IndexWriter indexWriter = getIndexWriter();
		// 创建document对象
		Document document = new Document();
		Field name = new TextField("name", "apache.txt", Store.YES);
		name.setBoost(10.0f);	// 设置相关度
		document.add(name);
		document.add(new TextField("name1", "我是name1", Store.YES));
		document.add(new TextField("name2", "我是name2", Store.YES));
		document.add(new LongField("content", 1000l, Store.NO));
		// 添加document'到索引库
		indexWriter.addDocument(document);
		// 关闭
		indexWriter.close();
	}


Solr安装及配置

从官方网站下载Solr

Solr的安装步骤:

1、安装tomcat
2、把solr目录中dist下的war包部署到tomcat下,并改名为便于访问的solr.war。
3、启动tomcat以使solr.war包自动解压。再关闭tomcat后,删除war包。
4、把Solr目录下example\lib\ext目录下的jar包添加到solr工程中,日志相关。
5、配置磁盘索引库solrhome,solr服务器所有配置文件保存的目录。在example下的solr目录就是一个solrhome。
将这个目录复制到自定义的路径,并改名为solrhome。改名只是便于理解……
6、配置solr工程和solrhome之间的关系,告诉solr工程solrhome的位置:
修改solr工程的web.xml:解开注释,并修改value值。
    <env-entry>
       <env-entry-name>solr/home</env-entry-name>
       <env-entry-value>D:\develop\solrhome</env-entry-value>
       <env-entry-type>java.lang.String</env-entry-type>
    </env-entry>

7、启动tomcat


Solr的后台管理界面














待续……




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值