导航:首页 > 净水问答 > solr过滤特殊字符

solr过滤特殊字符

发布时间:2022-07-19 09:33:04

⑴ solr查询某个字段最大值,如何实现

q:查询的关键字,此参数最为重要,例如,q=id:1,默认为q=*:*,类似于sql中的where 1=1。
fq(filter query):过滤查询,提供一个可选的筛选器查询。返回在q查询符合结果中同时符合的fq条件的查询结果,例如:q=id:1&fq=sort:[1 TO 5]&fq=section:0,找关键字id为1 的,并且sort是1到5之间,section=0的。还能写成fq=+sort[1 TO 5] +section:0]。性能方面的考虑:每个fq下面的记录都会单独缓存。可以考虑把经常在一起的fq条件用+方式写。
sort:排序方式,例如id desc 表示按照 “id” 降序。id desc, price asc先按id降序,再按price升序。sum(x_f, y_f) desc按x_f和y_f字段的和降序。
start,rows:分页参数,类似于start,limite的功能。啥都不输的话默认值分别为start=0,limit=10。

⑵ java web 怎么用solr

我们下载的Solr包后,进入Solr所在的目录,我们可以看到以下几个目录:build、client、dist、example、lib、site、src。下面分别对其进行介绍。
1) build:该目录是在ant build过程中生成的,其中包含了未被打包成jar或是war的class文件以及一些文档文件。
2) client:该目录包含了特定语言的Solr客户端API,使得使用其他语言的用户能通过HTTP用XML与Solr进行通话。现在该目录里面虽然包含javascript、python、ruby三个子目录,但是到目前为止只包含一部分的ruby的代码,其他语言仍是空的。另外,Solr的Java客户端称为SolrJ,其代码位于src/solrj目录下面。在之后的文章中我会详细介绍Solr客户端的使用。
3) dist:该目录包含build过程中产生的war和jar文件,以及相关的依赖文件。还记得上一篇文章中,我们在build 1.4版本的Solr源代码后需要部署example吗?其实就是将该目录下面的apache-solr-1.4.war部署到Jetty上面去,并重命名为solr.war。
4) example:这个目录实际上是Jetty的安装目录。其中包含了一些样例数据和一些Solr的配置。
其中一些子目录也比较重要,这里也对它们稍作介绍。
l example/etc:该目录包含了Jetty的配置,在这里我们可以将Jetty的默认端口从8983改为80端口。
l 将其中的8983端口换成80端口。注意更改端口后启动Jetty可能会提示你没有权限,你需要使用sudo java -jar start.jar来运行。
l example/multicore:该目录包含了在Solr的multicore中设置的多个home目录。在之后的文章中我会对其进行介绍。
l example/solr:该目录是一个包含了默认配置信息的Solr的home目录。
详见下面的“solr home说明”
l example/webapps:Jetty的webapps目录,该目录通常用来放置Java的Web应用程序。在Solr中,前面提到的solr.war文件就部署在这里。
5) lib:该目录包含了所有Solr的API所依赖的库文件。其中包括Lucene,Apache commons utilities和用来处理XML的Stax库。
6) site:该目录仅仅包含了Solr的官网的网页内容,以及一些教程的PDF文档。
7) src:该目录包含了Solr项目的整个源代码。这里对其各个子目录也做相应的介绍。
l src/java:该目录存放的是Solr使用Java编写的源代码。
l src/scripts:该目录存放的是配置Solr服务器的Unix BashShell脚本,在后面介绍多服务器配置中将会有重要的作用。
l src/solrj:前面提到过该目录存放的是Solr的Java版本的客户端代码。
l src/test:该目录存放的是测试程序的源代码和测试文件。
l src/webapp:该目录存放的是管理Solr的Web页面,包括Servlet和JSP文件,其构成了前面提到的WAR文件。管理Solr的JSP页面在web/admin目录下面,如果你有兴趣折腾Solr可以找到相应的JSP的页面对其进行设置
1.4.2 Solr home说明
所谓的Solr home目录实际上是一个运行的Solr实例所对应的配置和数据(Lucene索引)。在上一篇文章中我提到过在Solr的example/solr目录就是一个Solr用做示例的默认配置home目录。实际上example/multicore也是一个合法的Solr home目录,只不过是用来做mult-core设置的。那么我们来看看example/solr这个目录里面都有些什么。
example/solr目录下主要有以下一些目录和文件:
1) bin:如果你需要对Solr进行更高级的配置,该目录建议用来存放Solr的复制脚本。
2) conf :该目录下面包含了各种配置文件,下面列出了两个最为重要的配置文件。其余的.txt和.xml文件被这两个文件所引用,如用来对文本进行特殊的处理。
l conf/schema.xml:该文件是索引的schema,包含了域类型的定义以及相关联的analyzer链。
l conf/solrconfig.xml:该文件是Solr的主配置文件。
l conf/xslt:该目录包含了各种XSLT文件,能将Solr的查询响应转换成不同的格式,如:Atom/RSS等。
3) data:包含了Lucene的二进制索引文件。
4) lib:该目录是可选的。用来放置附加的Java JAR文件,Solr在启动时会自动加载该目录下的JAR文件。这就使得用户可以对Solr的发布版本(solr.war)进行扩展。如果你的扩展并不对Solr本身进行修改,那么就可以将你的修改部署到JAR文件中放到这里。

Solr是如何找到运行所需要的home目录的呢?
Solr首先检查名为solr.solr.home的Java系统属性,有几种不同的方式来设置该Java系统属性。一种不管你使用什么样的Java应用服务器或Servlet引擎都通用的方法是在调用Java的命令行中进行设置。所以,你可以在启动Jetty的时候显式地指定Solr的home目录java -Dsolr.solr.home=solr/ -jar start.jar。另一种通用的方法是使用JNDI,将home目录绑定到java:comp/env/solr/home。并向src/webapp/web/WEB-INF/web.xml添加以下一段代码:
1 <env-entry>
2 <env-entry-name>solr/home</env-entry-name>
3 <env-entry-value>solr/</env-entry-value>
4 <env-entry-type>java.lang.String</env-entry-type>
5 </env-entry>
实际上这段XML在web.xml文件中已经存在,你只需要把原来注释掉的xml取消注释,添加你所要指向的home目录即可。因为修改了web.xml文件,所以你需要运行antdist-war来重新打包之后再部署WAR文件。

最后,如果Solr的home目录既没有通过Java系统属性指定也没有通过JNDI指定,那么他将默认指向solr/。
在产品环境中,我们必须设置Solr的home目录而不是让其默认指向solr/。而且应该使用绝对路径,而不是相对路径,因为你有可能从不同的目录下面启动应用服务器。

注:Jetty 是一个开源的servlet容器,它为基于Java的web内容,例如JSP和servlet提供运行环境。Jetty是使用Java语言编写的,它的API以一组JAR包的形式发布。开发人员可以将Jetty容器实例化成一个对象,可以迅速为一些独立运行(stand-alone)的Java应用提供网络和web连接。

我们先从使用者的角度出发,最先看到的当然是servlet,因为Solr本身是个独立的网络应用程序,需要在Servlet容器中运行来提供服务,所以servlet是用户接触的最外层。我们看看org.apache.solr.servlet包。这个包很简单,只有两个类:SolrServlet和SolrUpdateServlet.我们很容易从类名中猜出这两个类的用途。
SolrServlet类继承HttpServlet类,只有四个方法:
· init()
· destroy()
· doGet()
· doPost()
SolrServlet类中除了普通的Java类对象(包括Servlet相关的)外,有四个Solr本身的类,还有一个Solr本身的异常。其中两个类和一个异常属于org.apache.solr.core包,两个类属于org.apache.solr.request包。属于core包的有:
· Config:
· SolrCore:
属于request包的有:
· SolrQueryResponse:
· QueryResponseWriter:
分析一下这个SolrServlet类。首先servlet会调用init()方法进行初始化:通过Context查找java:comp/env/solr/home来确定Solr的主目录(home),接着调用Config.setInstanceDir(home)方法设置这个实例的目录。然后通过SolrCore.getSolrCore()来获得一个SolrCore实例。destroy()方法将会在Servlet对象销毁时调用,仅仅调用core.close()关闭SolrCore实例。
当用户请求进来时doPost()简单地将任务交给doGet()完成,主要的任务由doGet()完成。分析一下doGet()方法:
1) 使用SolrCore和doGet()参数request生成一个SolrServletRequest对象(注意:这个SolrServletRequest类不是公开类,位于org.apache.solr.servlet包中,继承了SolrQueryRequestBase类,仅仅接受SolrCore和HttpServletRequest对象作为参数)
2) 然后SolrCore执行execute()方法(参数为SolrServletRequest和SolrQueryResponse)
由此可见,真正的处理核心是SolrCore的execute方法

⑶ solr组件的角色有哪些

Solr它是一种开放源码的、基于 Lucene Java 的搜索服务器,易于加入到 Web 应用程序中。

二、Solr 提供了层面搜索(就是统计)、命中醒目显示并且支持多种输出格式(包括XML/XSLT 和JSON等格式)。它易于安装和配置,而且附带了一个基于 HTTP 的

管理界面。Solr已经在众多大型的网站中使用,较为成熟和稳定。

三、Solr 包装并扩展了 Lucene,所以Solr的基本上沿用了Lucene的相关术语。更重要的是,Solr 创建的索引与 Lucene 搜索引擎库完全兼容。

四、通过对Solr 进行适当的配置,某些情况下可能需要进行编码,Solr 可以阅读和使用构建到其他 Lucene 应用程序中的索引。

五、此外,很多 Lucene 工具(如Nutch、 Luke)也可以使用Solr 创建的索引。可以使用 Solr 的表现优异的基本搜索功能,也可以对它进行扩展从而满足企业的需要。
solr的优点
通过上面Solr的简介,可知solr的优点包括以下几个方面:

①高级的全文搜索功能;

②专为高通量的网络流量进行的优化;

③基于开放接口(XML和HTTP)的标准;

④综合的HTML管理界面;

⑤可伸缩性-能够有效地复制到另外一个Solr搜索服务器;

⑥使用XML配置达到灵活性和适配性;

⑦可扩展的插件体系。
solr VS Lucene!?
在比较solr和Lucene之前,要知道什么是Lucene,那么首先就来回顾Lucene是个什么东东?

Lucene是一个基于Java的全文信息检索工具包,它不是一个完整的搜索应用程序,而是为你的应用程序提供索引和搜索功能。Lucene 目前是 Apache Jakarta(雅加达) 家族中的一个开源项目。也是目前最为流行的基于Java开源全文检索工具包。目前已经有很多应用程序的搜索功能是基于 Lucene ,比如Eclipse 帮助系统的搜 索功能。Lucene能够为文本类型的数据建立索引,所以你只要把你要索引的数据格式转化的文本格式,Lucene 就能对你的文档进行索引和搜索。
那么,solr和它相比,是”输“了?还是“赢”了呢?

其实,Solr与Lucene 并不是竞争对立关系,恰恰相反Solr 依存于Lucene,因为Solr底层的核心技术是使用Lucene 来实现的,Solr和Lucene的本质区别有以下三点:搜索服务器,企业级和管理。Lucene本质上是搜索库,不是独立的应用程序,而Solr是。Lucene专注于搜索底层的建设,而Solr专注于企业应用。Lucene不负责支撑搜索服务所必须的管理,而Solr负责。所以说,一句话概括 Solr: Solr是Lucene面向企业搜索应用的扩展。
下面是solr和 lucene的架构图: 

这个图很繁琐,看不懂,大家不要灰心,在后面的代码里你就能够了解了这个图所讲的。

不难看出,绿色的就是lucene的模块,而蓝色的就是solr扩展了lucene。从图上可以看出以下几点:

a. 一个真正的拥有动态字段(Dynamic Field)和唯一键(Unique Key)的数据模式(Data Schema) 
b. 对Lucene查询语言的强大扩展! 
c. 支持对结果进行动态的分组和过滤 
d. 高级的,可配置的文本分析 
e. 高度可配置和可扩展的缓存机制 
f. 性能优化 
g. 支持通过XML进行外部配置 
h. 拥有一个管理界面 
i. 可监控的日志 
j. 支持高速增量式更新(Fast incremental Updates)和快照发布(Snapshot Distribution)

说到这,solr的简介就到此结束了,相信大家也对solr有了初步的了解,下面开始介绍一下solr的常用属性有哪些?

solr的使用属性及配置文件
Document 包括一个或多个 Field。Field 包括名称、内容以及告诉 Solr 如何处理内容的元数据。

例如,Field可以包含字符串、数字、布尔值或者日期,也可以包含你想添加的任何类型,只需用在solr的配置文件中进行相应的配置即可。Field可以使用大量的选项来描述,这些

选项告诉 Solr 在索引和搜索期间如何处理内容。

现在,查看以下图片 中列出的重要属性的子集:

在这就先提一下solr的重要文件之一,就是schema.xml的配置文件。

(一) schema.xml

schema.xml这个配置文件可以在你下载solr包的安装解压目录的\solr\example\solr\collection1\conf中找到,它就是solr模式关联的文件。

打开这个配置文件,你会发现有详细的注释。模式组织主要分为三个重要配置:

一、Fieldtype

Fieldtype:就是属性类型的意思,像int,String,Boolean种类型,而在此配置文件中,FieldType就有这种定义属性的功能,看下面的图片: 

图片上有我们熟悉的int,String,boolean,那么,后面的配置,是什么呢?那么我们就来介绍一下后面的参数:

二、Field

Field:是添加到索引文件中出现的属性名称,而声明类型就需要用到上面的type,如图所示:

ps:①field: 固定的字段设置;②dynamicField: 动态的字段设置,用于后期自定义字段,*号通配符.例如: test_i就是int类型的动态字段。

还有一个特殊的字段Field,一般用于检索时用的字段这样就只对这一个字段进行索引分词就行了Field的dest字段如果有多个source一定要设置

⑷ solr 名称 关键字两个字段权重设置

大家都知道,在SQL脚本中设置多字段做关键字相对比较简单,例:primary
key(id1,id2)
,但用脚本建数据库就比较麻烦了。
下面我们来介绍一下具体的解决方法:
1.把要设置为关键字的其中一个字段设为主键。
2.在设为主键的字段上右键单击选择索引/健,出现索引/健对话框。
3.找到常规----列,单击右边的小按钮,出现索引列对话框。
4.至此,我们就可以选择几个字段作为关键字了。
注释:第一个步骤不能省略。

⑸ 集群 solr 搜索 怎么收集结果

Facet 是 solr 的高级搜索功能之一 , 可以给用户提供更友好的搜索体验 . 在搜索关键字的同时 ,能够按照 Facet 的字段进行分组并统计 .

二. Facet 字段
1. 适宜被Facet 的字段
一般代表了实体的某种公共属性 , 如商品的分类 , 商品的制造厂家 , 书籍的出版商等等 .
2. Facet 字段的要求
Facet 的字段必须被索引 . 一般来说该字段无需分词 , 无需存储 .
无需分词是因为该字段的值代表了一个整体概念 , 如电脑的品牌 ” 联想 ” 代表了一个整体概念 , 如果拆成 ” 联 ”,” 想 ” 两个字都不具有实际意义 . 另外该字段的值无需进行大小写转换等处理 , 保持其原貌即可 .
无需存储是因为一般而言用户所关心的并不是该字段的具体值 , 而是作为对查询结果进行分组的一种手段 , 用户一般会沿着这个分组进一步深入搜索 .
3. 特殊情况
对于一般查询而言 , 分词和存储都是必要的 . 比如 CPU 类型 ”Intel 酷睿 2 双核 P7570”,拆分成 ”Intel”,” 酷睿 ”,”P7570” 这样一些关键字并分别索引 , 可能提供更好的搜索体验 . 但是如果将 CPU 作为 Facet 字段 , 最好不进行分词 . 这样就造成了矛盾 , 解决方法为 ,将 CPU 字段设置为不分词不存储 , 然后建立另外一个字段为它的 COPY, 对这个 COPY 的字段进行分词和存储 .
schema.xml

<types>
<fieldType name="string" class="solr.StrField" omitNorms="true"/>
<fieldType name="tokened" class="solr.TextField" >
<analyzer>
……
</analyzer>
</fieldType>
……
</types>
<fields>
<field name=”cpu” type=”string” indexed=”true” stored=”false”/>
<field name=”cpuCopy” type=” tokened” indexed=”true” stored=”true”/>
……
</fields>
<Field source="cpu" dest="cpuCopy"/>

三. Facet 组件
Solr 的默认 requestHandler(org.apache.solr.handler.component.SearchHandler) 已经包含了 Facet 组件 (org.apache.solr.handler.component.FacetComponent). 如果自定义 requestHandler 或者对默认的 requestHandler 自定义组件列表 , 那么需要将 Facet 加入到组件列表中去 .
solrconfig.xml

<requestHandler name="standard" class="solr.SearchHandler" default="true">
……
<arr name="components">
<str>自定义组件名</str>
<str>facet</str>
……
</arr>
</requestHandler>

四. Facet 查询
进行 Facet 查询需要在请求参数中加入 ”facet=on” 或者 ”facet=true” 只有这样 Facet 组件才起作用 .
1. Field Facet
Facet 字段通过在请求中加入 ”facet.field” 参数加以声明 , 如果需要对多个字段进行 Facet查询 , 那么将该参数声明多次 . 比如

/select?q=联想
&facet=on
&facet.field=cpu
&facet.field=videoCard

返回结果 :

<lst name="facet_counts">
<lst name="facet_queries"/>
<lst name="facet_fields">
<lst name="cpu">
<int name="Intel 酷睿2双核 T6600">48</int>
<int name="Intel 奔腾双核 T4300">28</int>
<int name="Intel 酷睿2双核 P8700">18</int>
<int name="Intel 酷睿2双核 T6570">11</int>
<int name="Intel 酷睿2双核 T6670">11</int>
<int name="Intel 奔腾双核 T4400">9</int>
<int name="Intel 酷睿2双核 P7450">9</int>
<int name="Intel 酷睿2双核 T5870">8</int>
<int name="Intel 赛扬双核 T3000">7</int>
<int name="Intel 奔腾双核 SU4100">6</int>
<int name="Intel 酷睿2双核 P8400">6</int>
<int name="Intel 酷睿2双核 SU7300">5</int>
<int name="Intel 酷睿 i3 330M">4</int>
</lst>
<lst name="videoCard">
<int name="ATI Mobility Radeon HD 4">63</int>
<int name="NVIDIA GeForce G 105M">24</int>
<int name="NVIDIA GeForce GT 240M">21</int>
<int name="NVIDIA GeForce G 103M">8</int>
<int name="NVIDIA GeForce GT 220M">8</int>
<int name="NVIDIA GeForce 9400M G">7</int>
<int name="NVIDIA GeForce G 210M">6</int>
</lst>
</lst>
<lst name="facet_dates"/>
</lst>

各个 Facet 字段互不影响 , 且可以针对每个 Facet 字段设置查询参数 . 以下介绍的参数既可以应用于所有的 Facet 字段 , 也可以应用于每个单独的 Facet 字段 . 应用于单独的字段时通过

f.字段名.参数名=参数值

这种方式调用 . 比如 facet.prefix 参数应用于 cpu 字段 , 可以采用如下形式

f.cpu.facet.prefix=Intel

1.1 facet.prefix
表示 Facet 字段值的前缀 . 比如 ”facet.field=cpu&facet.prefix=Intel”, 那么对 cpu字段进行 Facet 查询 , 返回的 cpu 都是以 ”Intel” 开头的 ,”AMD” 开头的 cpu 型号将不会被统计在内 .
1.2 facet.sort
表示 Facet 字段值以哪种顺序返回 . 可接受的值为 true(count)|false(index,lex). true(count) 表示按照 count 值从大到小排列 . false(index,lex) 表示按照字段值的自然顺序( 字母 , 数字的顺序 ) 排列 . 默认情况下为 true(count). 当 facet.limit 值为负数时 ,默认 facet.sort= false(index,lex).
1.3 facet.limit
限制 Facet 字段返回的结果条数 . 默认值为 100. 如果此值为负数 , 表示不限制 .
1.4 facet.offset
返回结果集的偏移量 , 默认为 0. 它与 facet.limit 配合使用可以达到分页的效果 .
1.5 facet.mincount
限制了 Facet 字段值的最小 count, 默认为 0. 合理设置该参数可以将用户的关注点集中在少数比较热门的领域 .
1.6 facet.missing
默认为 ””, 如果设置为 true 或者 on, 那么将统计那些该 Facet 字段值为 null 的记录.
1.7 facet.method
取值为 enum 或 fc, 默认为 fc. 该字段表示了两种 Facet 的算法 , 与执行效率相关 .
enum 适用于字段值比较少的情况 , 比如字段类型为布尔型 , 或者字段表示中国的所有省份.Solr 会遍历该字段的所有取值 , 并从 filterCache 里为每个值分配一个 filter( 这里要求 solrconfig.xml 里对 filterCache 的设置足够大 ). 然后计算每个 filter 与主查询的交集 .
fc( 表示 Field Cache) 适用于字段取值比较多 , 但在每个文档里出现次数比较少的情况 .Solr 会遍历所有的文档 , 在每个文档内搜索 Cache 内的值 , 如果找到就将 Cache 内该值的count 加 1.
1.8 facet.enum.cache.minDf
当 facet.method=enum 时 , 此参数其作用 ,minDf 表示 minimum document frequency. 也就是文档内出现某个关键字的最少次数 . 该参数默认值为 0. 设置该参数可以减少 filterCache 的内存消耗 , 但会增加总的查询时间 ( 计算交集的时间增加了 ). 如果设置该值的话 ,官方文档建议优先尝试 25-50 内的值 .
2. Date Facet
日期类型的字段在文档中很常见 , 如商品上市时间 , 货物出仓时间 , 书籍上架时间等等 . 某些情况下需要针对这些字段进行 Facet. 不过时间字段的取值有无限性 , 用户往往关心的不是某个时间点而是某个时间段内的查询统计结果 . Solr 为日期字段提供了更为方便的查询统计方式 .当然 , 字段的类型必须是 DateField( 或其子类型 ).
需要注意的是 , 使用 Date Facet 时 , 字段名 , 起始时间 , 结束时间 , 时间间隔这 4 个参数都必须提供 .
与 Field Facet 类似 ,Date Facet 也可以对多个字段进行 Facet. 并且针对每个字段都可以单独设置参数 .
2.1 facet.date
该参数表示需要进行 Date Facet 的字段名 , 与 facet.field 一样 , 该参数可以被设置多次 , 表示对多个字段进行 Date Facet.
2.2 facet.date.start
起始时间 , 时间的一般格式为 ” 1995-12-31T23:59:59Z”, 另外可以使用 ”NOW”,”YEAR”,”MONTH” 等等 , 具体格式可以参考 org.apache.solr.schema. DateField 的 java doc.
2.3 facet.date.end
结束时间 .
2.4 facet.date.gap
时间间隔 . 如果 start 为 2009-1-1,end 为 2010-1-1.gap 设置为 ”+1MONTH” 表示间隔1 个月 , 那么将会把这段时间划分为 12 个间隔段 . 注意 ”+” 因为是特殊字符所以应该用 ”%2B” 代替 .
2.5 facet.date.hardend
取值可以为 true|false, 默认为 false. 它表示 gap 迭代到 end 处采用何种处理 . 举例说明 start 为 2009-1-1,end 为 2009-12-25,gap 为 ”+1MONTH”,hardend 为 false 的话最后一个时间段为 2009-12-1 至 2010-1-1;hardend 为 true 的话最后一个时间段为 2009-12-1 至 2009-12-25.
2.6 facet.date.other
取值范围为 before|after|between|none|all, 默认为 none.
before 会对 start 之前的值做统计 .
after 会对 end 之后的值做统计 .
between 会对 start 至 end 之间所有值做统计 . 如果 hardend 为 true 的话 , 那么该值就是各个时间段统计值的和 .
none 表示该项禁用 .
all 表示 before,after,all 都会统计 .
举例 :

&facet=on
&facet.date=date
&facet.date.start=2009-1-1T0:0:0Z
&facet.date.end=2010-1-1T0:0:0Z
&facet.date.gap=%2B1MONTH
&facet.date.other=all

返回结果 :

3. Facet Query
Facet Query 利用类似于 filter query 的语法提供了更为灵活的 Facet. 通过 facet.query 参数 , 可以对任意字段进行筛选 .
例 1:

&facet=on
&facet.query=date:[2009-1-1T0:0:0Z TO 2009-2-1T0:0:0Z]
&facet.query=date:[2009-4-1T0:0:0Z TO 2009-5-1T0:0:0Z]

返回结果 :

<lst name="facet_counts">
<lst name="facet_queries">
<int name="date:[2009-1-1T0:0:0Z TO 2009-2-1T0:0:0Z]">5</int>
<int name="date:[2009-4-1T0:0:0Z TO 2009-5-1T0:0:0Z]">3</int>
</lst>
<lst name="facet_fields"/>
<lst name="facet_dates"/></lst>

例 2:返回结果 :

例 3:

&facet=on
&facet.query=cpu:[A TO G]

返回结果 :

<lst name="facet_counts">
<lst name="facet_queries">
<int name="cpu:[A TO G]">11</int>
</lst>
<lst name="facet_fields"/>
<lst name="facet_dates"/>
</lst>

4. key 操作符
可以用 key 操作符为 Facet 字段取一个别名 .
例 :

&facet=on
&facet.field={!key=中央处理器}cpu
&facet.field={!key=显卡}videoCard

返回结果 :

<lst name="facet_counts">
<lst name="facet_queries"/>
<lst name="facet_fields">
<lst name="中央处理器">
<int name="Intel 酷睿2双核 T6600">48</int>
<int name="Intel 奔腾双核 T4300">28</int>
<int name="Intel 酷睿2双核 P8700">18</int>
<int name="Intel 酷睿2双核 T6570">11</int>
<int name="Intel 酷睿2双核 T6670">11</int>
<int name="Intel 奔腾双核 T4400">9</int>
<int name="Intel 酷睿2双核 P7450">9</int>
<int name="Intel 酷睿2双核 T5870">8</int>
<int name="Intel 赛扬双核 T3000">7</int>
<int name="Intel 奔腾双核 SU4100">6</int>
<int name="Intel 酷睿2双核 P8400">6</int>
<int name="Intel 酷睿2双核 SU7300">5</int>
<int name="Intel 酷睿 i3 330M">4</int>
</lst>
<lst name="显卡">
<int name="ATI Mobility Radeon HD 4">63</int>
<int name="NVIDIA GeForce G 105M">24</int>
<int name="NVIDIA GeForce GT 240M">21</int>
<int name="NVIDIA GeForce G 103M">8</int>
<int name="NVIDIA GeForce GT 220M">8</int>
<int name="NVIDIA GeForce 9400M G">7</int>
<int name="NVIDIA GeForce G 210M">6</int>
</lst>
</lst>
<lst name="facet_dates"/>
</lst>

5. tag 操作符和 ex 操作符
当查询使用 filter query 的时候 , 如果 filter query 的字段正好是 Facet 字段 , 那么查询结果往往被限制在某一个值内 .
例 :

&fq=screenSize:14
&facet=on
&facet.field=screenSize

返回结果 :

<lst name="facet_counts">
<lst name="facet_queries"/>
<lst name="facet_fields">
<lst name=" screenSize">
<int name="14.0">107</int>
<int name="10.2">0</int>
<int name="11.1">0</int>
<int name="11.6">0</int>
<int name="12.1">0</int>
<int name="13.1">0</int>
<int name="13.3">0</int>
<int name="14.1">0</int>
<int name="15.4">0</int>
<int name="15.5">0</int>
<int name="15.6">0</int>
<int name="16.0">0</int>
<int name="17.0">0</int>
<int name="17.3">0</int>
</lst>
</lst>
<lst name="facet_dates"/>
</lst>

可以看到 , 屏幕尺寸 (screenSize) 为 14 寸的产品共有 107 件 , 其它尺寸的产品的数目都是0, 这是因为在 filter 里已经限制了 screenSize:14. 这样 , 查询结果中 , 除了 screenSize=14 的这一项之外 , 其它项目没有实际的意义 .
有些时候 , 用户希望把结果限制在某一范围内 , 又希望查看该范围外的概况 . 比如上述情况 ,既要把查询结果限制在 14 寸屏的笔记本 , 又想查看一下其它屏幕尺寸的笔记本有多少产品 . 这个时候需要用到 tag 和 ex 操作符 .
tag 就是把一个 filter 标记起来 ,ex(exclude) 是在 Facet 的时候把标记过的 filter 排除在外 .
例 :

&fq={!tag=aa}screenSize:14
&facet=on
&facet.field={!ex=aa}screenSize

返回结果 :

<lst name="facet_counts">
<lst name="facet_queries"/>
<lst name="facet_fields">
<lst name=" screenSize">
<int name="14.0">107</int>
<int name="14.1">40</int>
<int name="13.3">34</int>
<int name="15.6">22</int>
<int name="15.4">8</int>
<int name="11.6">6</int>
<int name="12.1">5</int>
<int name="16.0">5</int>
<int name="15.5">3</int>
<int name="17.0">3</int>
<int name="17.3">3</int>
<int name="10.2">1</int>
<int name="11.1">1</int>
<int name="13.1">1</int>
</lst>
</lst>
<lst name="facet_dates"/>
</lst>

这样其它屏幕尺寸的统计信息就有意义了 .
五. SolrJ 对 Facet 的支持

SolrServer server = getSolrServer();//获取SolrServer
SolrQuery query = new SolrQuery();//建立一个新的查询
query.setQuery("*:*");
query.setFacet(true);//设置facet=on
query.addFacetField(new String[] { "cpu", "videoCard" });//设置需要facet的字段
query.setFacetLimit(10);//限制facet返回的数量
QueryResponse response = server.query(query);
List<FacetField> facets = response.getFacetFields();//返回的facet列表
for (FacetField facet : facets) {
System.out.println(facet.getName());
System.out.println("----------------");
List<Count> counts = facet.getValues();
for (Count count : counts) {
System.out.println(count.getName() + ":" + count.getCount());
}
System.out.println();
}

⑹ 如何使用Solr索引MySql数据库

在solr与tomcat整合文章中,我用的索引库是mycore,现在就以这个为例。
首先要准备jar包:solr-dataimporthandler-4.8.1.jar、solr-dataimporthandler-extras-4.8.1.jar和mysql-connector-java-5.0.7-bin.jar这三个包到solr的tomcat的webapps\solr\WEB-INF\lib下
在这个文件夹的conf下配置两个文件,添加一个文件。先配置solrconfig.xml。
在该文件下添加一个新节点。
<requestHandler name="/dataimport" class="org.apache.solr.handler.dataimport.DataImportHandler">
<lst name="defaults">
<str name="config">data-config.xml</str>
</lst>
</requestHandler>
在solrconfig.xml的同目录下创建data-config.xml。
配置:
复制代码
<dataConfig>
<dataSource type="JdbcDataSource"
driver="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/courseman"
user="root"
password="mysql" />
<document>
<entity name="student"
query="SELECT * FROM student">
<field column="id" name="id" />
<field column="name" name="name" />
<field column="gender" name="gender" />
<field column="major" name="major" />
<field column="grade" name="grade" />
</entity>
</document>
</dataConfig>
复制代码
schemal.xml的配置
复制代码
<?xml version="1.0" ?>
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding right ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a of the License at

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<schema name="example core one" version="1.1">
<fieldtype name="string" class="solr.StrField" sortMissingLast="true" omitNorms="true"/>
<fieldType name="long" class="solr.TrieLongField" precisionStep="0" positionIncrementGap="0"/>
<fieldType name="int" class="solr.TrieIntField" precisionStep="0" positionIncrementGap="0"/>
<!-- general -->
<field name="id" type="int" indexed="true" stored="true" />
<field name="gender" type="string" indexed="true" stored="true" />
<field name="name" type="string" indexed="true" stored="true" />
<field name="major" type="string" indexed="true" stored="true" />
<field name="grade" type="string" indexed="true" stored="true" />
<field name="_version_" type="long" indexed="true" stored="true"/>
<!-- field to use to determine and enforce document uniqueness. -->
<uniqueKey>id</uniqueKey>
<!-- field for the QueryParser to use when an explicit fieldname is absent -->
<defaultSearchField>name</defaultSearchField>
<!-- SolrQueryParser configuration: defaultOperator="AND|OR" -->
<solrQueryParser defaultOperator="OR"/>
</schema>
复制代码
默认的文件不是这样的,稍微改动了一下。
field 的type类型是根据fieldtype 的name定义的。class是solr自定义的不能更改。
shcema.xml文件的field字段的属性介绍:
(1)name:字段名称
(2)type:字段类型(此处type不是java类型,而是下面定义的fieldType)
(3)indexed:是否索引看true--solr会对这个字段进行索引,只有经过索引的字段才能被搜索、排序等;false--不索引
(4)stored:是否存储看true--存储,当我们需要在页面显示此字段时,应设为true,否则false。
(5)required:是否必须看true--此字段为必需,如果此字段的内容为空,会报异常;false--不是必需
(6)multiValued:此字段是否可以保存多个值看
(7)omitNorms:是否对此字段进行解析看有时候我们想通过某个字段的完全匹配来查询信息,那么设置 indexed="true"、omitNorms="true"。
(8)default:设置默认值
有这样一个FieldType描述:
<fieldType name="text_general" positionIncrementGap="100">
<analyzer type="index">
<tokenizer/>
<filter ignoreCase="true" words="stopwords.txt" enablePositionIncrements="true" />
<filter/>
</analyzer>
<analyzer type="query">
<tokenizer/>
<filter ignoreCase="true" words="stopwords.txt" enablePositionIncrements="true" />
<filter synonyms="synonyms.txt" ignoreCase="true" expand="true"/>
<filter/>
</analyzer>
</fieldType>
属性说明:
(1)name:类型名称,<field>中的type引用的就是这个name
(2)class:solr自定义的类型
(3)<analyzer type="index">定义建立索引时使用的分词器及过滤器
(4)<analyzer type="query">定义搜索时所使用的分词器及过滤器
(5)<tokenizer/>定义分词器
(6)<filter/>定义过滤器
uniqueKey属性
<uniqueKey>id</uniqueKey>
类似于数据表数据的id,solr索引库中最好定义一个用于标示document唯一性的字段,此字段主要用于删除document。
defaultSearchField属性
就是你在做query搜寻时若不指定特定栏位做检索时, Solr就会只查这个栏位.
<defaultSearchField>default</defaultSearchField>
Field属性
是用来复制你一个栏位里的值到另一栏位用. 如你可以将name里的东西到major里, 这样solr做检索时也会检索到name里的东西.
<Field source="name" dest="major"/>
现在可以将数据库的数据导入solr了。
点击Execute就可以了。

⑺ 求助:solr如何通过指定条件修改数据

修改主方法
public int saveContent(String enterpriseId, String enterpriseName, String lableType, String resouce, String pubDate,
String content) {

int state = 0;
LBHttpSolrServer server = SolrUtil.getSolrServer(ap.getEnterprisenewSolrUrl());
SolrQuery query = new SolrQuery();
query.set("q", "enterpriseId:" + enterpriseId);
try {
QueryResponse qr = server.query(query);
List<EnterpriseContentBean> contentList = qr.getBeans(EnterpriseContentBean.class);
// 设置需要保存的文章信息
for (EnterpriseContentBean bean : contentList) {
bean.setEnterpriseId(enterpriseId);
bean.setEnterpriseName(enterpriseName);
List<String> contents = new ArrayList<String>();
contents.add(content);
bean.setContent(contents);
bean.setPubDate(pubDate);
System.out.println("pubDate======>" + pubDate);
List<String> lableTypes = Arrays.asList(lableType.split(","));

bean.setLableType(lableTypes);
bean.setResource(resouce);
bean.setIsVisited_s("1");
}

server.addBeans(contentList);
server.commit();

} catch (SolrServerException e) {
state = 1;
System.out.println("修改solr数据报错");
e.printStackTrace();
} catch (IOException e) {
state = 1;
System.out.println("修改solr数据报错");
e.printStackTrace();
}
return state;

}

删除主方法
public int deletContent(String enterpriseId) {

LBHttpSolrServer server = SolrUtil.getSolrServer(ap.getEnterprisenewSolrUrl());
int state = 0;
try {
server.deleteById(enterpriseId);
server.commit();

} catch (SolrServerException e) {
state = 1;
System.out.println("删除solr数据报错");
e.printStackTrace();
} catch (IOException e) {
state = 1;
System.out.println("删除solr数据报错");
e.printStackTrace();
}

return state;
}

solr工具类
package com.dinfo.boc.utils;

import java.io.IOException;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;

import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.impl.LBHttpSolrServer;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.common.SolrDocumentList;
import org.apache.solr.common.SolrInputDocument;
import com.dinfo.boc.enterprise.bean.EnterpriseContentBean;
import com.dinfo.boc.enterprisenew.bean.SolrQueryResult;

/**
* 与Solr服务器交互的工具类
* @author qiuyj
*
*/
public class SolrUtil {

/**
* 获取与指定Solr地址的连接
* @param solrUrl
* @return
*/
public static LBHttpSolrServer getSolrServer(String solrUrl){
final int ONE_HUNDRED_MS = 10000000;

if(solrUrl == null || "".equals(solrUrl)){
throw new RuntimeException("Solr url can not be empty!");
}

LBHttpSolrServer solrServer = null;
try {
solrServer = new LBHttpSolrServer(solrUrl);
solrServer.setConnectionTimeout(ONE_HUNDRED_MS);
} catch (MalformedURLException e) {
e.printStackTrace();
} //SolrUtil.getSolrServer(solrUrl);

//solrServer.(100);
//solrServer.setMaxTotalConnections(100);

return solrServer;
}

/**
* 向指定的Solr地址添加一条数据
* @param solrUrl
* @param doc
* @throws Exception
*/
public static void add(String solrUrl, SolrInputDocument doc) throws Exception {
if(doc == null){
throw new RuntimeException("SolrInputDocument object can not be null!");
}

LBHttpSolrServer solr = getSolrServer(solrUrl);
solr.add(doc);
solr.commit();
}

/**
* 向指定的Solr地址用JavaBean添加一条数据
* @param solrUrl
* @param obj
* @throws Exception
*/
public static void add(String solrUrl, Object obj) throws Exception {
if(obj == null){
throw new RuntimeException("Object to be inserted can not be null!");
}

LBHttpSolrServer solr = getSolrServer(solrUrl);
solr.addBean(obj);
solr.commit();
}

/**
* 向指定Solr地址批量添加数据
* @param solrUrl
* @param docs
* @throws Exception
*/
@SuppressWarnings("unchecked")
public static void addAll(String solrUrl, Collection<? extends Object> objs) throws Exception {
if(objs == null){
throw new RuntimeException("Object collection can not be null!");
}
if(objs.size() == 0){
return;
}

LBHttpSolrServer solr = getSolrServer(solrUrl);

if(objs.iterator().next() instanceof SolrInputDocument){
solr.add((Collection<SolrInputDocument>)objs);
} else {
solr.addBeans(objs);
}
solr.commit();
}

/**
* 根据给定的id,从solr中删除对应信息
* @param solrUrl
* @param ids
*/
public static void deleteByIds(String solrUrl, String ... ids) throws Exception {
if(ids == null || ids.length == 0){
throw new RuntimeException("Ids can not be empty!");
}

LBHttpSolrServer solr = getSolrServer(solrUrl);
solr.deleteById(Arrays.asList(ids));
solr.commit();
}

public static void deleteByIds(String solrUrl, Integer ... ids) throws Exception {
if(ids == null || ids.length == 0){
throw new RuntimeException("Ids can not be empty!");
}

List<String> stringIdList = new ArrayList<>(ids.length);
for(Integer id : ids){
stringIdList.add("" + id);
}

LBHttpSolrServer solr = getSolrServer(solrUrl);
solr.deleteById(stringIdList);
solr.commit();
}

/**
* 删除指定Solr路径下符合指定查询条件的数据
* @param solrUrl
* @param condition
* @throws Exception
*/
public static void deleteByCondition(String solrUrl, String condition) throws Exception {
if(condition == null || "".equals(condition)){
throw new RuntimeException("Condition can not be empty!");
}

LBHttpSolrServer solr = getSolrServer(solrUrl);
solr.deleteByQuery(condition);
solr.commit();
}

/**
* 删除指定Solr路径下的所有数据
* @param solrUrl
* @throws Exception
*/
public static void deleteAll(String solrUrl) throws Exception {
deleteByCondition(solrUrl, "*:*");
}

/**
* 根据 指定查询条件从Solr中查询数据,并以SolrDocument的List形式返回
* @param solrUrl
* @param query
* @return
* @throws Exception
*/
public static SolrDocumentList queryAndGetSolrDocumentList(String solrUrl, SolrQuery query) throws Exception {
if(query == null){
throw new RuntimeException("SolrQuery object can not be null!");
}

LBHttpSolrServer solr = getSolrServer(solrUrl);
QueryResponse resp = solr.query(query);
return resp.getResults();
}

/**
* 根据 指定查询条件从Solr中查询数据,并以QueryResponse形式返回
* @param solrUrl
* @param query
* @return
* @throws Exception
*/
public static QueryResponse queryAndGetSolrQueryResponse(String solrUrl, SolrQuery query) throws Exception {
if(query == null){
throw new RuntimeException("SolrQuery object can not be null!");
}

LBHttpSolrServer solr = getSolrServer(solrUrl);
QueryResponse resp = solr.query(query);
return resp;
}

/**
* 根据 指定查询条件从Solr中查询数据,并以Java Bean的List形式返回
* @param solrUrl
* @param query
* @param returnClass 返回的List集合的泛型
* @return
* @throws Exception
*/
public static <T> List<T> queryAndGetBeanList(String solrUrl, SolrQuery query, Class<T> returnClass) throws Exception {
if(query == null){
throw new RuntimeException("SolrQuery object can not be null!");
}
if(returnClass == null){
throw new RuntimeException("Return class can not be null!");
}

LBHttpSolrServer solr = getSolrServer(solrUrl);
QueryResponse resp = solr.query(query);
return resp.getBeans(returnClass);
}

/**
* 根据 指定查询条件从Solr中查询数据,并以SolrQueryResult对象的形式返回,其中包含List对象和totalCount
* @param solrUrl
* @param query
* @param returnClass 返回的List集合的泛型
* @return
* @throws Exception
*/
public static <T> SolrQueryResult<T> queryAndGetSolrQueryResult(String solrUrl, SolrQuery query, Class<T> returnClass) throws Exception {
SolrQueryResult<T> result = new SolrQueryResult<T>();

if(query == null){
throw new RuntimeException("SolrQuery object can not be null!");
}
if(returnClass == null){
throw new RuntimeException("Return class can not be null!");
}

LBHttpSolrServer solr = getSolrServer(solrUrl);
solr.setConnectionTimeout(10000);
QueryResponse resp = solr.query(query);
List<T> resultList = resp.getBeans(returnClass);
long totalCount = resp.getResults().getNumFound();

result.setResultList(resultList);
result.setTotalCount(totalCount);

return result;
}

/**
* 根据 指定查询条件从Solr中查询数据,并以SolrQueryResult对象的形式返回,其中包含List对象和totalCount
* @param solrUrl
* @param query
* @param returnClass 返回的List集合的泛型
* @return
* @throws Exception
*/
public static <T> SolrQueryResult<T> queryAndGetSolrQueryResult(LBHttpSolrServer solr, SolrQuery query, Class<T> returnClass) throws Exception {
SolrQueryResult<T> result = new SolrQueryResult<T>();

if(query == null){
throw new RuntimeException("SolrQuery object can not be null!");
}
if(returnClass == null){
throw new RuntimeException("Return class can not be null!");
}

QueryResponse resp = solr.query(query);
List<T> resultList = resp.getBeans(returnClass);
long totalCount = resp.getResults().getNumFound();

result.setResultList(resultList);
result.setTotalCount(totalCount);

return result;
}

/**
* 用以过滤一些影响Solr查询的特殊字符,如左右括号、星号等
* @param str
* @return
*/
public static String filterSpecialCharacters(String str){
if(str == null){
return str;
}
str = str.replace("(", "\\(");
str = str.replace(")", "\\)");
str = str.replace("*", "\\*");
return str;
}

public static void updateSolrById(LBHttpSolrServer server){
SolrQuery query = new SolrQuery();
String id="";
int state=0;
String name="新疆金风科技股份有限公司";
query.set("q", "enterpriseId:"+id);
try {
QueryResponse qr = server.query(query);
List<EnterpriseContentBean> contentList = qr.getBeans(EnterpriseContentBean.class);
//设置需要保存的文章信息
for(EnterpriseContentBean bean:contentList){
// bean.setEnterpriseId(enterpriseId);
bean.setEnterpriseName(name);
bean.setResource("东方财富网港股频道");
}

server.addBeans(contentList);
server.commit();

} catch (SolrServerException e) {
state = 1;
e.printStackTrace();
} catch (IOException e) {
state = 1;
e.printStackTrace();
}
}
public static void main(String[] args) {
try {
=new LBHttpSolrServer("http://115.182.226.165:8008/solr/enterprisenew");
enterpriseServer.setConnectionTimeout(10000000);
updateSolrById(enterpriseServer);
System.out.println("over");
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}
}

⑻ solr 建索引的时候能对特殊字符做转义吗

解决方法:

在搜索的action中将输入的参数(kw为keywords的缩写)做转义处理,即

import org.apache.solr.client.solrj.util.ClientUtils;
String escapedKw = ClientUtils.escapeQueryChars(kw);
然后拿转义后的escapedKw去solr中查询,用户输入的参数kw的值不变用于回显到搜索框中。

阅读全文

与solr过滤特殊字符相关的资料

热点内容
消失模铸造用树脂砂 浏览:618
巩义污水处理费怎么收取的 浏览:225
饮水机从上盖溢水怎么回事 浏览:76
济南水景水处理设备 浏览:248
辐射水蒸馏后 浏览:63
污水处理剂化工 浏览:630
如何把污水盖给塞紧 浏览:72
一级树脂瓦厂家直销 浏览:42
污水管图s代表什么 浏览:428
DPF过滤器压差 浏览:851
污水处理厂空气监测有什么用 浏览:361
智能雨水收集回用一体机 浏览:83
污水池不渗水怎么办 浏览:18
肾过滤作用是什么 浏览:963
甲阶热固性酚醛树脂 浏览:555
水垢影响锅炉爆管分析报告 浏览:808
饮水机接水桶多少钱 浏览:662
污水打渣机不上水怎么办 浏览:574
污水处理厂账务处理怎么做 浏览:500
九级纯水是什么 浏览:433