本例我们使用类库和代码均来自:

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搜索基础的更多相关文章

  1. 关于Solr搜索标点与符号的中文分词你必须知道的(mmseg源码改造)

    关于Solr搜索标点与符号的中文分词你必须知道的(mmseg源码改造) 摘要:在中文搜索中的标点.符号往往也是有语义的,比如我们要搜索“C++”或是“C#”,我们不希望搜索出来的全是“C”吧?那样对程 ...

  2. 什么是Solr搜索

    什么是Solr搜索 一.Solr综述   什么是Solr搜索 我们经常会用到搜索功能,所以也比较熟悉,这里就简单的介绍一下搜索的原理. 当然只是介绍solr的原理,并不是搜索引擎的原理,那会更复杂. ...

  3. Solr搜索技术

    Solr搜索技术 今日大纲 回顾上一天的内容: 倒排索引 lucene和solr的关系 lucene api的使用 CRUD 文档.字段.目录对象(类).索引写入器类.索引写入器配置类.IK分词器 查 ...

  4. Solr系列五:solr搜索详解(solr搜索流程介绍、查询语法及解析器详解)

    一.solr搜索流程介绍 1. 前面我们已经学习过Lucene搜索的流程,让我们再来回顾一下 流程说明: 首先获取用户输入的查询串,使用查询解析器QueryParser解析查询串生成查询对象Query ...

  5. solr搜索应用

    非票商品搜索,为了不模糊查询影响数据库的性能,搭建了solr搜索应用,php从solr读取数据

  6. Problem L: 搜索基础之马走日

    Problem L: 搜索基础之马走日 Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 134  Solved: 91[Submit][Status][W ...

  7. Problem K: 搜索基础之棋盘问题

    Problem K: 搜索基础之棋盘问题 Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 92  Solved: 53[Submit][Status][W ...

  8. Problem J: 搜索基础之红与黑

    Problem J: 搜索基础之红与黑 Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 170  Solved: 100[Submit][Status][ ...

  9. solr搜索结果转实体类对象的两种方法

    问题:就是把从solr搜索出来的结果转成我们想要的实体类对象,很常用的情景. 1.使用@Field注解 @Field这个注解放到实体类的属性[字段]中,例如下面 public class User{ ...

随机推荐

  1. 三角形[HDU2039]

    三角形 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submiss ...

  2. HttpClient_用Apache HttpClient实现URL重定向

    很多网站都使用了URL重定向技术,把一个原始请求从一个位置路由到另一个位置.原因可能是多方面的,比如域名转发.URL缩写.隐私保护.在同一网站维持相似的域名等.本文讲述怎样使用Apache HTTPC ...

  3. CSS HTML链接去掉小手与增添小手

    style="cursor: hand" crosshair:精确定位“十”字形: text:文本“I”形: wait:等待,“沙漏”形: default:默认指针: help:帮 ...

  4. openstack是什么

    下面图片多来自互联网. 云计算: 云计算层次机构模型: IaaS 基础设施服务 PaaS 平台级服务 SaaS 软件级服务 官网:http://www.openstack.org/ openstack ...

  5. java web工程之Hibernate

    java web添加structs特性后再添加Hibernate特性,这可以通过右键工程->my eclipse出现工具条选中相应的条目,添加相应的属性, 添加完Hibernate后建立与数据库 ...

  6. HTML&CSS----练习做网页

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  7. HTML第一课总结

    1.图片热点: 规划出图片上的一个区域,可以做出超链接,直接点击图片区域就可以完成跳转的效果. 示例: 2.网页划区: 在一个网页里,规划出一个区域用来展示另一个网页的内容. 示例: 3.网页的拼接: ...

  8. 结合计划任务每天从Symantec官网下载离线病毒库

    #三种方法,由初级到高级 $numbers = 1..40 | Foreach {"{0:D3}" -f $_} #将数字类型格式化并转换为字符串类型使用-f字符串操作符 ForE ...

  9. SPOJ 3267 D-query(离散化+主席树求区间内不同数的个数)

    DQUERY - D-query #sorting #tree English Vietnamese Given a sequence of n numbers a1, a2, ..., an and ...

  10. HDU 2181 哈密顿绕行世界问题(经典DFS+回溯)

    哈密顿绕行世界问题 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total ...