Solr搜索基础
本例我们使用类库和代码均来自:
http://www.cnblogs.com/TerryLiang/archive/2011/04/17/2018962.html
使用C#来模拟搜索、索引建立、删除、更新过程,Demo截图如下:


一、准备工作:
先准备一个实体类Product:
public class Product
{
public string ID { get; set; }
public string Name { get; set; }
public String[] Features { get; set; }
public float Price { get; set; }
public int Popularity { get; set; }
public bool InStock { get; set; }
public DateTime Incubationdate_dt { get; set; }
}
再为这个实体类创建一个反序列化类ProductDeserializer:
class ProductDeserializer : IObjectDeserializer<Product>
{
public IEnumerable<Product> Deserialize(SolrDocumentList result)
{
foreach (SolrDocument doc in result)
{
yield return new Product()
{
ID = doc["id"].ToString(),
Name = doc["name"].ToString(),
Features = (string[])((ArrayList)doc["features"]).ToArray(typeof(string)),
Price = (float)doc["price"],
Popularity = (int)doc["popularity"],
InStock = (bool)doc["inStock"],
Incubationdate_dt = (DateTime)doc["incubationdate_dt"]
};
}
}
}
为项目引入EasyNet.Solr.dll。
二、创建搜索:
执行Solr客户端初始化操作:
#region 初始化
static List<SolrInputDocument> docs = new List<SolrInputDocument>();
static OptimizeOptions optimizeOptions = new OptimizeOptions();
static ISolrResponseParser<NamedList, ResponseHeader> binaryResponseHeaderParser = new BinaryResponseHeaderParser();
static IUpdateParametersConvert<NamedList> updateParametersConvert = new BinaryUpdateParametersConvert();
static ISolrUpdateConnection<NamedList, NamedList> solrUpdateConnection = new SolrUpdateConnection<NamedList, NamedList>() { ServerUrl = "http://localhost:8080/solr/" };
static ISolrUpdateOperations<NamedList> updateOperations = new SolrUpdateOperations<NamedList, NamedList>(solrUpdateConnection, updateParametersConvert) { ResponseWriter = "javabin" }; static ISolrQueryConnection<NamedList> connection = new SolrQueryConnection<NamedList>() { ServerUrl = "http://localhost:8080/solr/" };
static ISolrQueryOperations<NamedList> operations = new SolrQueryOperations<NamedList>(connection) { ResponseWriter = "javabin" }; static IObjectDeserializer<Product> exampleDeserializer = new ProductDeserializer();
static ISolrResponseParser<NamedList, QueryResults<Product>> binaryQueryResultsParser = new BinaryQueryResultsParser<Product>(exampleDeserializer);
#endregion
我们先模拟一个数据源,这里内置一些数据作为示例:
List<Product> products = new List<Product>();
Product juzi = new Product
{
ID = "SOLR1000",
Name = "浙江桔子",
Features = new String[] {
"色香味兼优",
"既可鲜食,又可加工成以果汁",
"果实营养丰富"},
Price = 2.0f,
Popularity = ,
InStock = true,
Incubationdate_dt = new DateTime(, , , , , , DateTimeKind.Utc)
};
products.Add(juzi); var doc = new SolrInputDocument();
doc.Add("id", new SolrInputField("id", juzi.ID));
doc.Add("name", new SolrInputField("name", juzi.Name));
doc.Add("features", new SolrInputField("features", juzi.Features));
doc.Add("price", new SolrInputField("price", juzi.Price));
doc.Add("popularity", new SolrInputField("popularity", juzi.Popularity));
doc.Add("inStock", new SolrInputField("inStock", juzi.InStock));
doc.Add("incubationdate_dt", new SolrInputField("incubationdate_dt", juzi.Incubationdate_dt)); docs.Add(doc); Product pingguo = new Product
{
ID = "SOLR1002",
Name = "陕西苹果",
Features = new String[] {
"味道甜美",
"光泽鲜艳",
"营养丰富"
},
Price = 1.7f,
Popularity = ,
InStock = true,
Incubationdate_dt = new DateTime(, , , , , , DateTimeKind.Utc)
};
products.Add(pingguo);
var doc2 = new SolrInputDocument();
doc2.Add("id", new SolrInputField("id", pingguo.ID));
doc2.Add("name", new SolrInputField("name", pingguo.Name));
doc2.Add("features", new SolrInputField("features", pingguo.Features));
doc2.Add("price", new SolrInputField("price", pingguo.Price));
doc2.Add("popularity", new SolrInputField("popularity", pingguo.Popularity));
doc2.Add("inStock", new SolrInputField("inStock", pingguo.InStock));
doc2.Add("incubationdate_dt", new SolrInputField("incubationdate_dt", pingguo.Incubationdate_dt)); docs.Add(doc2); dataGridView1.DataSource = products;
同时将这些数据添加到List<SolrInputDocument>中,SolrInputDocument是TerryLiang编写的文档交换实体,可以在他提供的源代码中看到。
1. 创建索引:
创建索引是指将原始数据传递给Solr,然后在Solr目录下创建指定格式文件,这些文件能够被Solr快速查询,如下图:

创建索引实际上就是用Update将数据POST给collection1,代码如下:
var result = updateOperations.Update("collection1", "/update", new UpdateOptions() { OptimizeOptions = optimizeOptions, Docs = docs });
var header = binaryResponseHeaderParser.Parse(result);
lbl_info.Text= string.Format("Update Status:{0} QTime:{1}", header.Status, header.QTime);
索引成功后我们可以在Solr管理界面查询:

注意:每次使用管理器搜索时,右上角都会显示搜索使用的URL:
http://localhost:8080/solr/collection1/select?q=*%3A*&wt=json&indent=true
这些参数的含义较为简单可以查询一些文档获取信息。
2. 创建查询
查询其实就是提交一个请求给服务器,等待服务器将结果返回的过程,可以使用任何语言只要能发起请求并接受结果即可,这里我们使用客户端。
先创建一个ISolrQuery对象,传入搜索关键字,关键字的构建方法可以从Solr管理界面推理出来:
假如我们要查询name中带“苹果”的信息,我们需要在管理界面输入:

如果想知道Solr是如何构建查询的话可以勾选DebugQuery选项,得到调试信息:

意思是只在Name这个列中检索。
所以我们代码中需要这么写:
ISolrQuery query = new SolrQuery("name:"+keyWord);
安全问题自行考虑。
但是如果要查询全部就简单多了:
ISolrQuery query = SolrQuery.All;
将查询条件发送给服务器之后再把服务器返回的数据还原成对象显示出来即完成了一次查询操作,具体操作代码如下:
ISolrQuery query = SolrQuery.All;
if (!string.IsNullOrWhiteSpace(keyWord))
{
query = new SolrQuery("name:"+keyWord);
}
var result = operations.Query("collection1", "/select", query, null);
var header = binaryResponseHeaderParser.Parse(result); var examples = binaryQueryResultsParser.Parse(result); lbl_info.Text= string.Format("Query Status:{0} QTime:{1} Total:{2}", header.Status, header.QTime, examples.NumFound);
dataGridView1.DataSource = examples.ToList();
3. 增量索引
实际上经常会有数据是新增或者改变的,那么我们就需要及时更新索引便于查询出新数据,就需要增量索引。这和初次索引一样,如果你想更新原有数据,那么将新数据再次提交一次即可,如果想增加提交不同数据即可。数据判断标准为id,这是个配置项,可以在中D:\apache-tomcat-7.0.57\webapps\solr\solr_home\collection1\conf\schema.xml找到:
<field name="id" type="string" indexed="true" stored="true" required="true" multiValued="false" />
可以理解为主键。
代码如下:
var docs = new List<SolrInputDocument>();
Product hetao = new Product
{
ID = "SOLR1003",
Name = "陕西山核桃",
Features = new String[] {
"营养好吃",
"微量元素丰富",
"补脑"
},
Price = 1.7f,
Popularity = ,
InStock = true,
Incubationdate_dt = new DateTime(, , , , , , DateTimeKind.Utc)
};
var doc2 = new SolrInputDocument();
doc2.Add("id", new SolrInputField("id", hetao.ID));
doc2.Add("name", new SolrInputField("name", hetao.Name));
doc2.Add("features", new SolrInputField("features", hetao.Features));
doc2.Add("price", new SolrInputField("price", hetao.Price));
doc2.Add("popularity", new SolrInputField("popularity", hetao.Popularity));
doc2.Add("inStock", new SolrInputField("inStock", hetao.InStock));
doc2.Add("incubationdate_dt", new SolrInputField("incubationdate_dt", hetao.Incubationdate_dt));
docs.Clear();
docs.Add(doc2); var result = updateOperations.Update("collection1", "/update", new UpdateOptions() { OptimizeOptions = optimizeOptions, Docs = docs });
var header = binaryResponseHeaderParser.Parse(result); lbl_info.Text= string.Format("Update Status:{0} QTime:{1}", header.Status, header.QTime);
4. 删除索引
和数据库删除一样,当然按照主键进行删除。传入删除Option同时带入主键名和主键值发送给服务器即可。
具体操作代码如下:
var result = updateOperations.Update("collection1", "/update", new UpdateOptions() { OptimizeOptions = optimizeOptions, DelById = new string[] { id } });
var header = binaryResponseHeaderParser.Parse(result);
lbl_info.Text=string.Format("Update Status:{0} QTime:{1}", header.Status, header.QTime);
这样就完成了一个最基本的创建索引,更新删除索引和查询的过程,本例查询速度并没有直接操作管理界面那么快,原因在于序列化和反序列化,延续上述提到的:任何语言只要能发起请求和接收响应即可以查询,可以避免这个过程,提高查询效率。
Solr搜索基础的更多相关文章
- 关于Solr搜索标点与符号的中文分词你必须知道的(mmseg源码改造)
关于Solr搜索标点与符号的中文分词你必须知道的(mmseg源码改造) 摘要:在中文搜索中的标点.符号往往也是有语义的,比如我们要搜索“C++”或是“C#”,我们不希望搜索出来的全是“C”吧?那样对程 ...
- 什么是Solr搜索
什么是Solr搜索 一.Solr综述 什么是Solr搜索 我们经常会用到搜索功能,所以也比较熟悉,这里就简单的介绍一下搜索的原理. 当然只是介绍solr的原理,并不是搜索引擎的原理,那会更复杂. ...
- Solr搜索技术
Solr搜索技术 今日大纲 回顾上一天的内容: 倒排索引 lucene和solr的关系 lucene api的使用 CRUD 文档.字段.目录对象(类).索引写入器类.索引写入器配置类.IK分词器 查 ...
- Solr系列五:solr搜索详解(solr搜索流程介绍、查询语法及解析器详解)
一.solr搜索流程介绍 1. 前面我们已经学习过Lucene搜索的流程,让我们再来回顾一下 流程说明: 首先获取用户输入的查询串,使用查询解析器QueryParser解析查询串生成查询对象Query ...
- solr搜索应用
非票商品搜索,为了不模糊查询影响数据库的性能,搭建了solr搜索应用,php从solr读取数据
- Problem L: 搜索基础之马走日
Problem L: 搜索基础之马走日 Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 134 Solved: 91[Submit][Status][W ...
- Problem K: 搜索基础之棋盘问题
Problem K: 搜索基础之棋盘问题 Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 92 Solved: 53[Submit][Status][W ...
- Problem J: 搜索基础之红与黑
Problem J: 搜索基础之红与黑 Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 170 Solved: 100[Submit][Status][ ...
- solr搜索结果转实体类对象的两种方法
问题:就是把从solr搜索出来的结果转成我们想要的实体类对象,很常用的情景. 1.使用@Field注解 @Field这个注解放到实体类的属性[字段]中,例如下面 public class User{ ...
随机推荐
- WPF之TextBox
1. TextBox实现文字垂直居中 TextBox纵向长度比较长但文字字体比较小的时候,在输入时就会发现文字不是垂直居中的. 而使用中我们发现,TextBox虽然可以设置文字的水平对齐方式,但却没有 ...
- JS模态窗口返回值兼容问题解决方案
因系统要兼容原IE已使用的关闭方法,经调试测得,需对window.dialogArguments进行再较验,不然易出问题. function OKEnd(vals) { if (vals == nul ...
- OpenCV2.4.10 Mac Qt Configuration
Download OpenCV 2.4.10 Download CMake 2.8 Open CMake and choose the source code directory and build ...
- Qt connect parent widget 连接父控件的信号槽
Qt中的信号槽系统是不同类中间传递数据的神器,如果连接父子空间之间的信号槽很重要,在父类中实例化子类的时候一定要注意将父类连上,不然信号槽无法使用,比如若子类是个对话框Dialog类,一定不要忘了加t ...
- swift文件上传及表单提交
var carData:NSMutableDictionary = NSMutableDictionary(); var request:NSMutableURLRequest = NSMutable ...
- 使用ProxychainsMac下安装及配置
下面几种解决方式 一.先在VPS用composer把Laravel给拖回来,本地你就别想用Composer正常下载Laravel回来了 二.使用全局代理,暂时木有折腾过在终端下怎么折腾,GUI可以使用 ...
- HTML&CSS----练习(运算符)
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- 如何进行SCCM中客户端记录信息维护
SCCM 部署完毕之后,不久我们就会发现客户端代理状态,因为重装系统,非正常的退域,长时间不开机,导致客户端状态有不可用的,有过期的,重复的记录很多.当然我们可以手动的快速删除重复的记录,那么怎么能做 ...
- 获取Dell,Lenovo电脑的保修期
2015-4-6写的代码(Dell), 不知道如何对报错进行友好化处理,于是采用了"非空"和"非空的补集"处理方式. $service = New-WebSer ...
- yum安装 lnmp
yum nginx是不行的 so,制作一个repo vi /etc/yum.repos.d/nginx.repo 写上 CentOS: [nginx] name=nginx repo baseurl= ...