一、基本概念
二、solr索引操作
三、java操作solr例子
一、基本概念
因为Solr 包装并扩展了 Lucene,所以Solr的基本上沿用了Lucene的相关术语。更重要的是,Solr 创建的索引与 Lucene 搜索引擎库完全兼容。
通过对Solr 进行适当的配置,某些情况下可能需要进行编码,Solr 可以阅读和使用构建到其他 Lucene 应用程序中的索引。例如,Field 可以包含字符串、数字、布尔值或者日期,也可以包含你想添加的任何类型,只需用在solr的配置文件中进行相应的配置即可。Field 可以使用大量的选项来描述,这些选项告诉 Solr 在索引和搜索期间如何处理内容。
属性名称 | 描述 |
Indexed | Indexed Field 可以进行搜索和排序。你还可以在 indexed Field 上运行 Solr 分析过程,此过程可修改内容以改进或更改结果。 |
Stored | stored Field 内容保存在索引中。这对于检索和醒目显示内容很有用,但对于实际搜索则不是必需的。例如,很多应用程序存储指向内容位置的指针而不是存储实际的文件内容。 |
通过indexed=true可以使得一个field可以被搜索,如果你有一个字段title设置的是indexed=true,那么q=title:csdn就是在搜索标题中含有csdn的document。如果你设置indexed=false,就算你有符合的数据也无法搜索出来。
stored=true意味着你可以在结果中看到这个field,通过fl参数可以控制是否在结果中显示,如果你设置stored=false,就算你有符合的数据看不到该field。
二、solr索引操作
在Solr中,通过向部署在servlet容器中的Solr
Web应用程序发送HTTP请求来启动索引和搜索。Solr接受请求,确定要使用的适当SolrRequestHandler,然后处理请求。通过HTTP以同样的方式返回响应。默认配置返回Solr的标准XML响应。你也可以配置Solr的备用响应格式,如json、csv格式的文本。
索引就是接受输入元数据(数据格式在schema.xml中进行配置)并将它们传递给Solr,从而在HTTP
Post XML 消息中进行索引的过程。你可以向Solr索引servlet传递四个不同的索引请求:
add/update允许您向Solr添加文档或更新文档。直到提交后才能搜索到这些添加和更新。
commit告诉Solr,应该使上次提交以来所做的所有更改都可以搜索到。
optimize重构Lucene的文件以改进搜索性能。索引完成后执行一下优化通常比较好。如果更新比较频繁,则应该在使用率较低的时候安排优化。一个索引无需优化也可以正常地运行。优化是一个耗时较多的过程。
delete可以通过id或查询来指定。按id删除将删除具有指定id的文档;按查询删除将删除查询返回的所有文档。
Lucene中操作索引也有这几个步骤,但是没有更新。Lucene更新是先删除,然后添加索引。因为更新索引在一定情况下,效率没有先删除后添加的效率好。
上面有提到schema.xml这个配置,这个配置可以在你下载solr包的安装解压目录的solr-5.3.2/example/example-DIH/solr/solr/conf中找到,它就是solr模式关联的文件。打开这个配置文件,你会发现有详细的注释。
模式组织主要分为三个重要配置
types 部分是一些常见的可重用定义,定义了 Solr(和 Lucene)如何处理 Field。也就是添加到索引中的xml文件属性中的类型,如int、text、date等
fileds是你添加到索引文件中出现的属性名称,而声明类型就需要用到上面的types
其他配置有
uniqueKey 唯一键,这里配置的是上面出现的fileds,一般是id、url等不重复的。在更新、删除的时候可以用到。
三、java操作solr例子例子(下载地址)
我们知道如果想要使数据加入到Solr服务器中,在schema.xml必须要存在与其对应的Filed标签声明,如果我们要添加一个对象(比如商品对象)每次去一个一个的setFiled,这样比较麻烦,Solr允许使用javaBean的方式,将一个对象之间保存到solr服务器中。
思路:
1、首先在schema.xml中定义自己的Product对象的具体字段
2.、然后在java中建立实体对象,并且一定要在属性或set方法上添加@Field(nameValue)注解。(org.apache.solr.client.solrj.beans.Field)
3、最后我们在junit里面测试。
首先java中建立实体对象
我在org.springframework.data.solr.example.model创建了一个Product类
里面的@Field(nameValue)中的nameValue需要和schema.xml的有具体的field与之对应(如果字段不对应会报unknown field 'xxx')
package org.springframework.data.solr.example.model;
import java.util.List;
import org.apache.solr.client.solrj.beans.Field;
public class Product implements SearchableProduct {
@Field(ID_FIELD)
private String id;
@Field(NAME_FIELD)
private String name;
@Field(CATEGORY_FIELD)
private List<String> categories;
@Field(WEIGHT_FIELD)
private Float weight;
@Field(PRICE_FIELD)
private Float price;
@Field(POPULARITY_FIELD)
private Integer popularity;
@Field(AVAILABLE_FIELD)
private boolean available;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<String> getCategories() {
return categories;
}
public void setCategories(List<String> categories) {
this.categories = categories;
}
public Float getWeight() {
return weight;
}
public void setWeight(Float weight) {
this.weight = weight;
}
public Float getPrice() {
return price;
}
public void setPrice(Float price) {
this.price = price;
}
public Integer getPopularity() {
return popularity;
}
public void setPopularity(Integer popularity) {
this.popularity = popularity;
}
public boolean isAvailable() {
return available;
}
public void setAvailable(boolean available) {
this.available = available;
}
@Override
public String toString() {
return "Product [id=" + id + ", name=" + name + ", categories=" + categories + ", weight=" + weight + ", price=" + price + ", popularity=" + popularity + ", available=" + available + "]";
}
}
2、测试
1、这里首先创建了10个商品
2、通过findByPopularity方法查询对象
最后在@After注解下的tearDown方法将对象删除
package org.springframework.data.solr.example;
import java.util.List;
import org.junit.After;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.solr.core.query.result.FacetFieldEntry;
import org.springframework.data.solr.core.query.result.FacetPage;
import org.springframework.data.solr.example.model.Product;
import org.springframework.data.solr.example.repository.SolrProductRepository;
import org.springframework.data.solr.example.repository.SolrSearchableFields;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:org/springframework/data/solr/example/applicationContext.xml")
public class ITestSolrProductRepository extends AbstractSolrIntegrationTest {
@Autowired
SolrProductRepository repo;
@After
public void tearDown() {
repo.deleteAll();
}
@Test
public void testQuery() {
Assert.assertEquals(0, repo.count());
List<Product> baseList = createProductList(10);
repo.save(baseList);
Assert.assertEquals(baseList.size(), repo.count());
Page<Product> popularProducts = repo.findByPopularity(20);
Assert.assertEquals(1, popularProducts.getTotalElements());
Assert.assertEquals("2", popularProducts.getContent().get(0).getId());
}
}