主要讲一下solr面板的使用:

查询

q:     查询用  语法: name:刘中华      支持通配符

  ? 表示单个任意字符的通配

  * 表示多个任意字符的通配(不能在检索的项开始使用*或者?符号)

  ~ 表示模糊检索,如检索拼写类似于”roam”的项这样写:roam将找到形如foam和roams的单词;roam0.8,检索返回相似度在0.8以上的记录。

  AND、|| 布尔操作符

  OR、&& 布尔操作符

  NOT、!、-(排除操作符不能单独与项使用构成查询)

  + 存在操作符,要求符号”+”后的项必须在文档相应的域中存在²

  ( ) 用于构成子查询

  [] 包含范围检索,如检索某时间段记录,包含头尾,date:[201507 TO 201510]

  {} 不包含范围检索,如检索某时间段记录,不包含头尾date:{201507 TO 201510}

fq : filter query 过滤查询  比如:查询日期范围  last_modified:[2019-04-19  TO 2019-04-27]

sort: 排序。格式如下:字段名 排序方式;如   id desc 表示按id字段降序排列查询结果。 中间没有分号  是空格

fl: field list。指定查询结果返回哪些字段。多个时以空格“ ”或逗号“,”分隔。不指定时,默认全返回。

分组facet:

参考博客:https://blog.csdn.net/sgq1991/article/details/78051256

Facet 的字段必须被索引 . 一般来说该字段无需分词 , 无需存储 .

Solr提供了4种类型的Fact

<lst name="facet_counts">
<lst name="facet_queries"/>
<lst name="facet_fields"/>
<lst name="facet_dates"/>
<lst name="facet_ranges"/>
</lst>
  1. facet_queries:代表自定义条件查询facet,类似数据库的count函数
  2. facet_fields    :代表根据字段分组查询,类似数据库的group by count的组合
  3. facet_dates :根据日期区间分组查询
  4. facet_ranges:当然了,日期有区间,数字也有,这个就是根据数字分组查询

facet query(个人感觉就像count()作用)

Facet Query 用户自定义条件查询facet,他提供了非常灵活的Facet.通过facet.query参数,可以对任意字段进行筛选.下面通过实例来阐述。基本上他的用法,都会在我实例中体现出来

例一:日期区间查询,这个区间的数目为5个

url为:

&facet=true
&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]

面板为:

例2:数字区间统计

url为:

&facet=on
&facet.query=date:[2009-1-1T0:0:0Z TO 2009-2-1T0:0:0Z]
&facet.query=price:[* TO 5000]

facet.field(这就是类似于数据库的group by 加上count的功能)

实例一:最简单的field facet

&facet=true
&facet.field=brand
&facet.field=price
"facet_counts":{
"facet_queries":{},
"facet_fields":{
"brand":[
"苹果",4,
"联想",3,
"惠普",2],
"price":[
"1100.0",2,
"2200.0",2,
"3300.0",2,
"1200.0",1,
"2100.0",1,
"4400.0",1]},
"facet_dates":{},
"facet_ranges":{}}}

从返回结果可以看出各个field字段互不影响;而且可以针对,下面实例会体现

facet.prefix(个人感觉就是像在facet.field的上一层过滤一下,比如只统计品牌名称是联开头的电脑)

&facet.field=brand
&facet.field=price
&f.brand.facet.prefix=联
"facet_counts":{
"facet_queries":{},
"facet_fields":{
"brand":[
"联想",3],
"price":[
"1100.0",2,
"2200.0",2,
"3300.0",2,
"1200.0",1,
"2100.0",1,
"4400.0",1]},
"facet_dates":{},
"facet_ranges":{}}}

温馨提示:上面的facet.prefix就是一个参数名,这个很容易误解为两个,因为他中间有个点

上面介绍了facet.field参数,下面介绍field fact的其他参数

1).facet.prefix
表示Facet字段值的前缀.比如facet.field=cpu&facet.prefix=Intel,那么对cpu字段进行Facet查询,返回的cpu都是以“Intel”开头的。
2).facet.sort
表示Facet字段值以哪种顺序返回.可接受的值为true(count)|false(index,lex). true(count)表示按照count降序; false(index,lex)表示按照字段值升序(字母,数字的顺序)排列.默认情况下为true(count).当facet.limit值为负数时,默认facet.sort= false(index,lex).
3).facet.limit
限制Facet字段返回的结果条数.默认值为100.如果此值为负数,表示不限制.
4).facet.offset
返回结果集的偏移量,默认为0.它与facet.limit配合使用可以达到分页的效果.
5).facet.mincount
限制了Facet字段值的最小count,默认为0.合理设置该参数可以将用户的关注点集中在少数比较热门的领域.相当于group by having
6).facet.missing
默认为””,如果设置为true或者on,那么将统计那些该Facet字段值为null的记录.
7).facet.method
取值为enum或fc,默认为fc.该字段表示了两种Facet的算法,与执行效率相关.
enum适用于字段值比较少的情况,比如字段类型为布尔型,或者字段表示中国的所有省份.Solr会遍历该字段的所有取值,并从filterCache里为每个值分配一个filter(这里要求solrconfig.xml里对filterCache的设置足够大).然后计算每个filter与主查询的交集.
fc(表示Field Cache)适用于字段取值比较多,但在每个文档里出现次数比较少的情况.Solr会遍历所有的文档,在每个文档内搜索Cache内的值,如果找到就将Cache内该值的count加1.
8).facet.enum.cache.minDf
当facet.method=enum时,此参数其作用,minDf表示minimum document frequency.也就是文档内出现某个关键字的最少次数.该参数默认值为0.设置该参数可以减少filterCache的内存消耗,但会增加总的查询时间(计算交集的时间增加了).如果设置该值的话,官方文档建议优先尝试25-50内的值.

Date Facet(专门对时间的一个统计)

日期类型的字段在文档中很常见,如商品上市时间,货物出仓时间,书籍上架时间等等.某些情况下需要针对这些字段进行Facet.不过时间字段的取值有无限性,用户往往关心的不是某个时间点而是某个时间段内的查询统计结果. Solr为日期字段提供了更为方便的查询统计方式.当然,字段的类型必须是DateField(或其子类型)。

需要注意的是,使用Date Facet时,字段名,起始时间,结束时间,时间间隔这4个参数都必须提供.与Field Facet类似,Date Facet也可以对多个字段进行Facet.并且针对每个字段都可以单独设置参数。  

&facet.date=birthday
&facet.date.start=2014-01-00T09:15:00Z
&facet.date.end=2014-12-00T09:15:00Z
&facet.date.gap=%2B1MONTH
"facet_counts":{
"facet_queries":{},
"facet_fields":{},
"facet_dates":{
"birthday":{
"2013-12-31T09:15:00Z":0,
"2014-01-31T09:15:00Z":0,
"2014-02-28T09:15:00Z":0,
"2014-03-28T09:15:00Z":0,
"2014-04-28T09:15:00Z":0,
"2014-05-28T09:15:00Z":0,
"2014-06-28T09:15:00Z":0,
"2014-07-28T09:15:00Z":0,
"2014-08-28T09:15:00Z":0,
"2014-09-28T09:15:00Z":1,
"2014-10-28T09:15:00Z":5,
"2014-11-28T09:15:00Z":3,
"gap":"+1MONTH",
"start":"2013-12-31T09:15:00Z",
"end":"2014-12-28T09:15:00Z"}},
"facet_ranges":{}}}
1).facet.date
该参数表示需要进行Date Facet的字段名,与facet.field一样,该参数可以被设置多次,表示对多个字段进行Date Facet.
2).facet.date.start
起始时间,时间格式为1995-12-31T23:59:59Z
3).facet.date.end
结束时间.
4).facet.date.gap
时间间隔.如果start为2009-1-1,end为2010-1-1.gap设置为+1MONTH表示间隔1个月,那么将会把这段时间划分为12个间隔段.
注意+因为是特殊字符所以应该用%2B代替.
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.
6).facet.date.other
取值范围为before|after|between|none|all,默认为none,before会对start之前的值做统计,after会对end之后的值做统计,between会对start至end之间所有值做统计.如果hardend为true的话,那么该值就是各个时间段统计值的和.none表示该项禁用.all表示before,after,all都会统计.

实例参考,演示fact.date.other、跟单独对某个字段起作用

&facet.date=birthday
&facet.date.start=2014-01-00T09:15:00Z
&facet.date.end=2014-12-00T09:15:00Z
&facet.date.gap=%2B1MONTH
&facet.date.other=all
&f.birthday.facet.mincount=3 --单独对某个字段起作用,把统计值小于3的过滤掉
"facet_counts":{
"facet_queries":{},
"facet_fields":{},
"facet_dates":{
"birthday":{
"2014-10-28T09:15:00Z":5,
"2014-11-28T09:15:00Z":3,
"gap":"+1MONTH",
"start":"2013-12-31T09:15:00Z",
"end":"2014-12-28T09:15:00Z",
"before":0,
"after":0,
"between":9}},
"facet_ranges":{}}}

Facet Range

范围统计分组统计,跟Date Facet一样,只是他们定位的字段的类型不同,Data Fact是做日期的分组统计的,而Fact Range是做数字分组统计的,在次强调,是做数字分组统计的,对于字符串,日期是不可以的。

参数跟上面的Date Facet基本一致,如下,就不做解释了,参考Date Facet的各个参数

1.    facet.range
2. facet.range.start
3. facet.range.end
4. facet.range.gap
5. facet.range.hardend
6. facet.range.other
7. facet.range.include

参考实例

&facet.range=price
&facet.range.start=1000
&facet.range.end=5000
&facet.range.gap=1000
&f.price.facet.mincount=2--单独对某个字段起作用,把统计值小于2的过滤掉

返回结果如下:

"facet_counts":{
"facet_queries":{},
"facet_fields":{},
"facet_dates":{},
"facet_ranges":{
"price":{
"counts":[
"1000.0",3,
"2000.0",3,
"3000.0",2],
"gap":1000.0,
"start":1000.0,
"end":5000.0}}}}

key 操作符(别名)

上面已经介绍了facet的四类统计,下面介绍一下key,什么是key?

答:key操作符可以为Facet字段取一个别名。哦原来如此简单!

参考实例:

参数
&facet=true
&facet.query=brand:联想 AND price:1100
返回结果
"facet_counts":{
"facet_queries":{
"brand:联想 AND price:1100":1},
"facet_fields":{},
"facet_dates":{},
"facet_ranges":{}}}
--------------------------------
参数
&facet=true
&facet.query={!key=联想}brand:联想 AND price:1100
返回结果
"facet_counts":{
"facet_queries":{
"联想":1},
"facet_fields":{},
"facet_dates":{},
"facet_ranges":{}}}

从上面可以看出来,这样可以让字段名统一起来,方便我们拿到请求数据后,封装成自己的对象

tag操作符和ex操作符(就是防止查询的条件来污染分组结果)

这个也非常的重要,看下应用场景,当查询使用filter query 或者q的时候,如果filter query的字段正好是Facet字段,那么查询结果往往被限制在某一个值内.

参考实例

&fq=price:[1000 TO 2000]
&facet.field=price
"facet_counts":{
"facet_queries":{},
"facet_fields":{
"price":[
"1100.0",2,
"1200.0",1,
"2100.0",0,
"2200.0",0,
"3300.0",0,
"4400.0",0]},
"facet_dates":{},
"facet_ranges":{}}}

从返回的结果可以看到fq将查询的结果集限制在了price 在1000 至 2000之间,其他范围的统计没有实际意义。

有些时候,用户希望把结果限制在某一个范围以内,又希望查看该范围外的概况,像上述情况,用户想把结果限制在(price)1000~2000之间,但是又想查看其他价格区间有多少产品。这个时候需要用到tag和ex操作符.tag就是把一个filter标记起来,ex(exclude)是在Facet的时候把标记过的filter排除在外.

参考实例

&fq={!tag=aa}price:[1000 TO 2000]
&facet.field={!ex=aa}price

返回结果

"facet_counts":{
"facet_queries":{},
"facet_fields":{
"price":[
"1100.0",2,
"2200.0",2,
"3300.0",2,
"1200.0",1,
"2100.0",1,
"4400.0",1]},
"facet_dates":{},
"facet_ranges":{}}}

这样其它价格区间的统计信息就有意义了.

Facet 字段设计

一、Facet字段的要求

Facet的字段必须被索引.一般来说该字段无需分词,无需存储.

无需分词是因为该字段的值代表了一个整体概念,如电脑的品牌”联想”代表了一个整体概念,如果拆成”联”,”想”两个字都不具有实际意义.另外该字段的值无需进行大小写转换等处理,保持其原貌即可.

无需存储是因为一般而言用户所关心的并不是该字段的具体值,而是作为对查询结果进行分组的一种手段,用户一般会沿着这个分组进一步深入搜索.

二、特殊情况

对于一般查询而言,分词和存储都是必要的.比如CPU类型“Intel 酷睿2双核 P7570”,拆分成“Intel”,“酷睿”,“P7570”这样一些关键字并分别索引,可能提供更好的搜索体验.但是如果将CPU作为Facet字段,最好不进行分词.这样就造成了矛盾,解决方法为,将CPU字段设置为不分词不存储,然后建立另外一个字段为它的COPY,对这个COPY的字段进行分词和存储.

<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>
<copyField source="cpu" dest="cpuCopy"/>

高亮

https://www.jianshu.com/p/cbb938c62e0e

hl: high light 高亮。hl=true表示启用高亮

hl.fl 设定高亮显示的字段,用空格或逗号隔开的字段列表。要启用某个字段的highlight功能,就得保证该字段在schema中是stored。如果该参数未被给出,那么就会高亮默认字段 standard handler会用df参数,dismax字段用qf参数。你可以使用星号去方便的高亮所有字段。如果你使用了通配符,那么要考虑启用hl.requiredFieldMatch选项。
hl.requireFieldMatch 如果置为true,除非用hl.fl指定了该字段,查询结果才会被高亮。它的默认值是false。
hl.usePhraseHighlighter 如果一个查询中含有短语(引号框起来的)那么会保证一定要完全匹配短语的才会被高亮。
hl.highlightMultiTerm 如果使用通配符和模糊搜索,那么会确保与通配符匹配的term会高亮。默认为false,同时hl.usePhraseHighlighter要为true。
hl.fragsize 返回的最大字符数。默认是100.如果为0,那么该字段不会被fragmented且整个字段的值会被返回。

java API

推荐博客:   https://blog.csdn.net/qq_37334135/article/details/76862508

其实就是solrJ的搜索。最底层的都是他,无论是   spring-boot-starter-data-solr   还是   spring-data-solr  都是这个solrJ的封装。

 <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-solr</artifactId>
</dependency>
spring:
datasource:
data:
solr:
host: http://127.0.0.1:8983/solr/

根据id搜索

   @Autowired
private SolrClient client; //根据id查找
@RequestMapping("/")
public Object testSolr() throws IOException, SolrServerException {
SolrDocument document = client.getById("test", "2");
System.out.println(document);
return document;
}

带条件查询

@RequestMapping("/list")
public Object query() throws Exception {
SolrQuery query = new SolrQuery();
query.set("q", "id:3&&name:张三");
QueryResponse response = solrClient.query("test", query);
SolrDocumentList results = response.getResults();
return results;
}

分组

     query.setStart((page-1)*pageSize);
query.setRows(pageSize);
QueryResponse response = solrClient.query(solrCollection, query);
// 获取查询结果
SolrDocumentList results = response.getResults();
//总条数
long numFound = results.getNumFound();

新增

@RequestMapping("/add")
public Object add() throws Exception {
SolrInputDocument document = new SolrInputDocument();
document.addField("id", 1002L);
document.addField("item_brand", "三星");
document.addField("item_goodsid", "66666");
document.addField("item_seller", "三星旗舰店");
document.addField("item_title", "三星千元机震撼来袭");
document.addField("item_category", "手机");
document.addField("item_price", "1499");
document.addField("item_image", "http://xiaomi.jpg");
document.addField("last_modified", "2019-04-22");
UpdateResponse add = solrClient.add("test",document);
int status = add.getStatus();
solrClient.commit("test");
return status;
}

分组(facet)

 @RequestMapping("/facet")
public void groupBy() throws Exception{
SolrQuery query = new SolrQuery();//建立一个新的查询
query.setQuery("f01:徐娜");
query.setFacet(true);//设置facet=on
query.addFacetField(new String[] { "tablename"});//设置需要facet的字段
query.setFacetLimit(10);//限制facet返回的数量
QueryResponse response = solrClient.query("MRD-7800",query);
List<FacetField> facets = response.getFacetFields();//返回的facet列表
for (FacetField facet : facets) {
System.out.println(facet.getName());
System.out.println("----------------");
List<FacetField.Count> counts = facet.getValues();
for (FacetField.Count count : counts) {
System.out.println(count.getName() + ":" + count.getCount());
}
System.out.println();
}
}

高亮

有个大坑,高亮的字段必须是分词的。麻蛋,浪费我快一天的时间排查。

@RequestMapping("/hightLiang2")
public void hightLiang2() throws Exception{
SolrQuery query = new SolrQuery();//建立一个新的查询
query.setQuery("\"徐娜\"");
// 设置默认搜素域
query.set("df", "onekey_keywords");
// 设置高亮显示
query.setHighlight(true);
query.addHighlightField("f01,f02,f03");
query.setHighlightSimplePre("<em style=\"color:red\">");
query.setHighlightSimplePost("</em>");
QueryResponse response = solrClient.query("MRD-7800",query);
// 获取查询结果
SolrDocumentList solrDocumentList = response.getResults();
//获取高亮显示数据
Map<String, Map<String, List<String>>> highlighting = response.getHighlighting();
// 遍历查询结果
for (SolrDocument solrDocument : solrDocumentList) {
// 获取高亮显示的集合
System.out.println(solrDocument);
String vid = (String) solrDocument.get("vid");
Map<String, List<String>> listMap = highlighting.get(vid);
for (Map.Entry<String, List<String>> entry : listMap.entrySet()) {
System.out.println("字段名字 = " + entry.getKey() + ", 字段值 = " + entry.getValue());
}
}
}
SolrDocument{f01=徐娜, f03=2014-08-11 20:55:57, f02=39, f05=72, f04=界心每百总天况件要第几他器按加或石, f07=七天连锁酒店, f06=性就眼则位以法常满需红该主成导难品老力即点素感回不月适要采最照果文往基教想会导里认线证几心作重十经合交五过织何过按直万增自六资而断进专没千车道长党合派眼何记体革做商方白战格复很得争经拉性, f08=4385694211245723, tablename=jdmb, vid=100, createId=1, _version_=1632676338865274880}
字段名字 = f01, 字段值 = [<em style="color:red">徐</em><em style="color:red">娜</em>]

solr的搜索的更多相关文章

  1. solr简单搜索案例

    solr简单搜索案例 使用Solr实现电商网站中商品信息搜索功能,可以根据关键字搜索商品信息,根据商品分类.价格过滤搜索结果,也可以根据价格进行排序,实现分页. 架构分为: 1. solr服务器 2. ...

  2. Solr 空间搜索配置、按经纬度计算距离排序

    Solr 空间搜索配置 1. 在solr目录下的找到conf文件夹下的schema.xml. <fields> <!-- 在fields元素中添加如下代码 --> <fi ...

  3. Solr 全文搜索

    ## 1. 概述 在本文中,我们将探讨一个[Apache Solr](http://lucene.apache.org/solr/)搜索引擎中的基本概念 - 全文搜索. Apache Solr是一个开 ...

  4. 项目之solr全文搜索工具之创建项目索引库

    以创建项目baotao core为例 1.  在example目录下创建baotao-solr文件夹: 2.  将./solr下的solr.xml拷贝到baotao-solr目录下: 3.  在bao ...

  5. 项目之solr全文搜索工具的安装

    1. Solr简介 Solr是一个基于Lucene的Java搜索引擎服务器.Solr 提供了层面搜索.命中醒目显示并且支持多种输出格式(包括 XML/XSLT 和 JSON 格式).它易于安装和配置, ...

  6. Solr -- 实时搜索

    在solr中,实时搜索有3种方案 ①soft commit,这其实是近实时搜索,不能完全实时. ②RealTimeGet,这是实时,但只支持根据文档ID的查询. ③和第一种类似,只是触发softcom ...

  7. .net中运用solr提升搜索效率(入门)

    概述: 在开发网站的时候经常有要对某些内容查询的需求.此时如果基于数据库查询来做搜索功能,由于要对多个字段做模糊匹配,效率往往非常糟糕.这种情况就可以用Solr来提升搜索的效率.Solr是一个独立的企 ...

  8. Lucene/Solr企业级搜索学习资源

    Solr是一个独立的企业级搜索应用服务器,它对外提供类似于Web-service的API接口.用户可以通过http请求,向搜索引擎服务器提交一定格式的XML文件,生成索引:也可以通过Http GSol ...

  9. 提高solr的搜索速度

    之前是使用12台机分布式搜索,1台为主机做索引并分发给子机,8台做大索引搜索服务,3 台做小索引搜索服务,配置基本是内存在4-8G,cpu:2-8core的服务器,索引的大小为8G.搜索的响应时间 是 ...

随机推荐

  1. c/c++ 多线程 std::lock

    多线程 std::lock 当要同时操作2个对象时,就需要同时锁定这2个对象,而不是先锁定一个,然后再锁定另一个.同时锁定多个对象的方法:std::lock(对象1.锁,对象2.锁...) 额外说明: ...

  2. luajit官方性能优化指南和注解

    luajit是目前最快的脚本语言之一,不过深入使用就很快会发现,要把这个语言用到像宣称那样高性能,并不是那么容易.实际使用的时候往往会发现,刚开始写的一些小test case性能非常好,经常毫秒级就算 ...

  3. 4.13Python数据处理篇之Matplotlib系列(十三)---轴的设置

    目录 目录 前言 (一)设置轴的范围 1.同时对于x,y轴设置 2.分别对与x,y轴的设置 (二)设置刻度的大小 1.普通的刻度设置 2.添加文本的刻度设置 3.主副刻度的设置 (三)设置轴的数据 1 ...

  4. python 3.7 配置mysql数据库

    一. mysql驱动安装 1.mysqlclient(推荐使用)    2.pymysql 二.django操作数据库     1.django配置连接数据库         settings.py ...

  5. 我的第一个python web开发框架(30)——定制ORM(六)

    在开发中,查询操作是使用最多的,而查询列表是其中之一,查询列表可分为分页查询和不分页查询(它们之间多了一次总记录数查询),还可以分为单表查询和多表关联查询,返回的结构体根据前端使用的表单框架不同而有所 ...

  6. 浏览器仿EXCEL表格插件 版本更新 - 智表ZCELL产品V1.3发布

    智表(zcell)是一款浏览器仿excel表格jquery插件.智表可以为你提供excel般的智能体验,支持双击编辑.设置公式.设置显示小数精度.下拉框.自定义单元格.复制粘贴.不连续选定.合并单元格 ...

  7. 大数据平台Lambda架构详解

    Lambda架构由Storm的作者Nathan Marz提出.旨在设计出一个能满足.实时大数据系统关键特性的架构,具有高容错.低延时和可扩展等特. Lambda架构整合离线计算和实时计算,融合不可变( ...

  8. 使用idea搭建Scala 项目

    主要内容 Intellij IDEA开发环境简介 Intellij IDEA Scala开发环境搭建 Intellij IDEA常见问题及解决方案 Intellij IDEA常用快捷键 1. Inte ...

  9. vscode 编写vue

    开启保存时检查代码语法 安装 让配置生效 添加新配置 cnpm install mockjs -D

  10. SQL语句检索数据排序及过滤

    阅读目录 一:排序检索数据 二:过滤数据 三:高级数据过滤 四:用通配符进行过滤 回到顶部 一:排序检索数据 1.1 排序数据 比如查询数据库中表数据的时候,我们使用如下语句: select * fr ...