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{ ...
随机推荐
- Extjs3.3 + swfUpload2.2 实现多文件上传组件
[该上传组件已经停止更新,该上传组件已经在项目中使用.在使用过程中如果发现bug请大家回复此贴.2011-02-27] 主要是为了用swfUpload实现上传,为了新鲜好玩. 理解swfUpload可 ...
- Assets/Sciprts/GameSciprt.js(97,46): BCE0044: expecting :, found ','.
function BuildDeck() { var totalRobots:int=4; var card:Object; var i:int; for(i=0;i<totalRobots;i ...
- Designing CSS Layouts With Flexbox Is As Easy As Pie
This article is an updated excerpt of the chapter “Restyle, Recode, Reimagine With CSS3″ from our Sm ...
- Lazy Load, 延迟加载图片的 jQuery 插件【备忘】
http://www.neoease.com/lazy-load-jquery-plugin-delay-load-image/ jQuery Unveil – 另一款非常轻量的延迟加载插件 http ...
- [Cocos2d-x For WP8]Hello world
[Cocos2d-x For WP8]Hello world Cocos2d-x For WP8使用C++开发,使用cocos2d-xv0.13同样的接口,Cocos2d-x For WP8的相关项目 ...
- Noi 2016
考砸只能说自己弱 Noi不是生活的全部, 人们也不会永远止步于失败. 大家加油 可以+我的qq:582744883
- ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES) ERROR 2013 (HY00 ...
- Toll-Free Bridge
引 在深入了解桥接机制的时候看到一篇好文,虽然已经很久远,但是忍不住看了好几遍,心中诸多不解一扫而光.在此放上链接: 原文:http://ridiculousfish.com/blog/posts/b ...
- [转]在Entity Framework中使用LINQ语句分页
本文转自:http://diaosbook.com/Post/2012/9/21/linq-paging-in-entity-framework 我们知道,内存分页效率很低.并且,如果是WebForm ...
- YII 查找View的5种方式
别名开头,路径指定view文件@app/views/site/about.php //开头,使用 app目录下面的views//site/about.php /开头,使用当前Module中的views ...