搜索
您的当前位置:首页Solr 功能使用

Solr 功能使用

时间:2022-08-04 来源:智榕旅游
Solr 功能使用

1. 准备阶段

创建一个user schema,对其进行各种业务操作。

1.1. User元数据结构

{ \"id\": \"10000000000\ \"screenName\": \"张三\ \"name\": \"张三\ \"province\": 33, \"city\": 1, \"location\": \"浙江 杭州\ \"description\": \"张三科技有限公司\ \"url\": \"http://blog.sina.com.cn/u/1000000000\ \"profileImageUrl\": \"http://tp2.sinaimg.cn/000000000000000000000\ \"userDomain\": \"zhangsan\ \"gender\": \"m\ \"followersCount\": 538, \"friendsCount\": 445, \"statusesCount\": 1204, \"favouritesCount\": 0, \"createdAt\": \"Apr 27, 2011 12:37:22 AM\ \"following\": false, \"verified\": false, \"verifiedType\": 220, \"allowAllActMsg\": true, \"allowAllComment\": false, \"followMe\": false, \"avatarLarge\": \"http://tp2.sinaimg.cn/000000000000\ \"onlineStatus\": 538, \"biFollowersCount\": 110, \"lang\": \"zh-cn\ \"verifiedReason\": \"\ \"weihao\": \"\ \"statusId\": \"3677329383941849\ \"birthYear\": 1980, \"birthMonth\": 11, \"birthDay\": 12 } 1.2. Solr schema设计

 增加一个copyField text用于文本搜索  增加各种类型的动态字段,方便扩展 omitNorms=\"true\"/> omitNorms=\"true\"/> omitNorms=\"true\"/> id class=\"com.chenlb.mmseg4j.solr.MMSegTokenizerFactory\" mode=\"complex\" name=\"double\" class=\"solr.TrieDoubleField\" precisionStep=\"0\" positionIncrementGap=\"0\"/>

1.3. 数据导入

原始数据是JSON格式的,写了个简单的导入程序。 /** * Benjamin Xie on 2015年3月27日 at yoyosys.com */ package foo; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.InputStream; import java.io.InputStreamReader; import java.text.SimpleDateFormat; import java.util.Locale; import java.util.Map; import org.apache.solr.client.solrj.impl.CloudSolrClient; import org.apache.solr.common.SolrInputDocument; import com.google.gson.Gson; public class ImportFromJson { int counter = 0; while ((line = reader.readLine()) != null) { Gson gson = new Gson(); String line = null; CloudSolrClient client = getSolrClient(); SimpleDateFormat fromFormat = new SimpleDateFormat(\"MMM dd, yyyy hh:mm:ss aa\SimpleDateFormat solrFormat = new SimpleDateFormat(\"yyyy-MM-dd'T'HH:mm:ss'Z'\"); public void run() { File jsonFile = new File(\"/Users/Benjamin/Workspace/part-r-00099\"); InputStream is = null; BufferedReader reader = null; try { is = new FileInputStream(jsonFile); reader = new BufferedReader(new InputStreamReader(is)); } public ImportFromJson() { Locale.ENGLISH); } } Map user = gson.fromJson(line, Map.class); SolrInputDocument doc = new SolrInputDocument(); for (String key : user.keySet()) { } client.add(doc); counter++; if (counter % 500 == 0) { } client.commit(); Object value = user.get(key); if (key.equals(\"createdAt\")) { } doc.setField(key, solrFormat.format(fromFormat.parse(value.toString()))); doc.setField(key, value); } else { client.commit(); } catch (Exception e) { } // TODO e.printStackTrace(); // TODO } finally { public CloudSolrClient getSolrClient() { } public static void main(String[] args) { ImportFromJson test = new ImportFromJson(); test.run(); CloudSolrClient client = new CloudSolrClient(\"172.16.5.2:2181\"); client.setDefaultCollection(\"user\"); client.connect(); return client; } } 总共365051条记录,顺便感叹一下耗时,只花了5毫秒:

2. 功能使用

solr提供了多种语言的sdk,上面导入数据使用的是solrj,以下我就只用使用url访问了,具体支持的语言: SolRuby DelSolr Ruby Ruby https://github.com/rsolr/rsolr https://github.com/avvo/delsolr acts_as_solr Flare SolPHP SolrJ Python API PySolr SolPerl Solr.pm SolrForrest SolrSharp SolColdfusion SolrNet AJAX Solr Rails Rails PHP Java Python Python Perl Perl Forrest/Cocoon C# ColdFusion .NET AJAX http://acts-as-solr.rubyforge.org/, http://rubyforge.org/projects/background-solrhttp://wiki.apache.org/solr/Flare http://wiki.apache.org/solr/SolPHP http://wiki.apache.org/solr/SolJava http://wiki.apache.org/solr/SolPython http://code.google.com/p/pysolr/ http://wiki.apache.org/solr/SolPerl http://search.cpan.org/~garafola/Solr-0.03/lib/Solr.pm http://wiki.apache.org/solr/SolrForrest http://www.codeplex.com/solrsharp http://solcoldfusion.riaforge.org/ http://code.google.com/p/solrnet/ http://github.com/evolvingweb/ajax-solr/wiki 2.1. 基本查询

http://172.16.5.2:8983/solr/user_shard2_replica1/select?q=*:*&wt=json&indent=true&start=0&row=10&sort=followersCount+desc 解释:

 查询条件“*:*”,查询所有数据

 格式化返回格式json:wt=json&indent=true  从0条开始,返回10条记录:start=0&row=10

 按照用户粉丝量倒叙返回:sort=followersCount+desc,“+”号可使用空格

代替

更多的常用参数:

 fq:对查询结果的二次筛选,且会把查询的结果缓存起来,下次同样的查询

将直接命中缓存

 fl:对返回的结果字段进行限制,例如我只想返回id

更丰富的使用规范说明:

https://cwiki.apache.org/confluence/display/solr/Query+Syntax+and+Parsing

2.2. 权重查询DisMax

以上面的schema为例,假设我需要查询所有“九江”的用户。地区值是存放在location字段中的,也有可能用户只在location中只存放了“江西”,但是description中有可能存放了和九江相关的介绍,这样这个用户只能说有可能也是九江的,在查询是我希望确定是九江的用户排在前面。这个时候就可以用到权

重这个概念了。

上面的应用场景查询方式:

http://172.16.5.2:8983/solr/user_shard2_replica1/select?q=text:%E4%B9%9D%E6%B1%9F&start=0&rows=10&wt=json&indent=true&defType=dismax&qf=location^10+description^3

权重查询常用参数:

 defType=dismax,属于基本查询的参数,权重查询时必须是dismax

 qf:权重设置,例如location^10就是location字段的权重设置,值得大小

我理解是相对的,默认不设置的为1

 mm:当查询条件(指的是参数个数,而非表达式个数)为多个时,设置返回

最少匹配的次数

另外还有很多参数,我还没有理解设计意图。

2.3. 函数

有几种途径可以使用函数:  查询的条件中  排序的参数  返回结果计算  计算权重时

支持的函数,比较多:http://wiki.apache.org/solr/FunctionQuery

2.4. 按维度统计结果 faceting

faceting可以实现按照数据的间隔、类型来统计数量。

举例三个应用场景,分别使用不同的统计方式:

1. 统计用户注册年份分布,使用时间facet方式:

http://172.16.5.2:8983/solr/user_shard2_replica1/select?q=*:*&rows=0&wt=json&indent=true&facet=true&facet.date=createdAt&facet.date.gap=%2B1YEAR&facet.date.start=2008-01-01T00:00:00Z&facet.date.end=2015-12-31T23:59:59Z

参数:

 facet=true :启用faceting  facet.date :faceting字段

 facet.date.gap=+1YEAR :一年一个区间  facet.date.start :开始统计时间  facet.date.end :统计的结束时间

结果: \"facet_counts\":{ \"facet_queries\":{}, \"facet_fields\":{}, \"facet_dates\":{ \"createdAt\":{ \"2008-01-01T00:00:00Z\":0, \"2009-01-01T00:00:00Z\":6021, \"2010-01-01T00:00:00Z\":83066, \"2011-01-01T00:00:00Z\":135665, \"2012-01-01T00:00:00Z\":89044, \"2013-01-01T00:00:00Z\":42318, \"2014-01-01T00:00:00Z\":8937, \"2015-01-01T00:00:00Z\":0, \"gap\":\"+1YEAR\}}, \"facet_ranges\":{}, \"facet_intervals\":{}}}

2. 统计用户性别,常规facet方式:

http://172.16.5.2:8983/solr/user_shard2_replica1/select?q=*:*&rows=0&wt=json&indent=true&facet=true&facet.field=gender

参数:

 facet=true

 facet.field=gender :按性别统计

结果: \"facet_counts\":{ \"facet_queries\":{}, \"facet_fields\":{ \"gender\":[ \"f\ \"m\}, \"facet_dates\":{}, \"facet_ranges\":{}, \"facet_intervals\":{}}}

3. 统计用户粉丝区间,按照数据值区间统计:

http://172.16.5.2:8983/solr/user_shard2_replica1/select?q=*:*&rows=0&wt=json&indent=true&facet=true&facet.query=followersCount[0%20TO%20999]&facet.query=followersCount[1000%20TO%209999]&facet.query=followersCount[10000%20TO%20*]

参数:

 facet=true

 facet.query=followersCount[0 TO 999] :统计数值区间,可以添加多个

结果: \"facet_counts\":{ \"facet_queries\":{ \"followersCount[0 TO 999]\":365051, \"followersCount[1000 TO 9999]\":365051, \"followersCount[10000 TO *]\":365051 }, \"facet_fields\":{}, \"facet_dates\":{}, \"facet_ranges\":{}, \"facet_intervals\":{}}}

2.5. 在查询结果中高亮显示查询关键词

我一直觉得高亮显示其实可以在前端用javascript轻松实现,但是solr支持的高亮是有区别于js显示的,因为solr支持按照搜索的关键词做文章摘要。

http://172.16.5.2:8983/solr/user_shard2_replica1/select?q=description:%E7%BE%8E%E5%A5%B3&hl=true&hl.fl=description&hl.fragsize=10

参数:

 hl=true :启用高亮

 hl.fl=description :高亮显示的字段  hl.fragsize=10 :包含高亮的摘要长度

2.6. 统计查询结果statistics

可以对结果进行统计,包括:总数、Sum、最小值、最大值、空值的记录数等。

http://172.16.5.1:8983/solr/user_shard1_replica1/select?q=%E6%B1%9F%E8%A5%BF&indent=true&rows=0&stats=true&stats.field=followersCount

参数:

 stats=true :启用统计

 stats.field=followersCount :统计字段

结果: \"stats\":{ \"stats_fields\":{ \"followersCount\":{ \"min\":0.0, \"max\":310696.0, \"count\":5108, \"missing\":0, \"sum\":3121689.0, \"sumOfSquares\":2.27193470687E11, \"mean\":611.1372357086923, \"stddev\":6641.770648621739, \"facets\":{}}}}}

2.7. 其它功能

下面几个功能虽然实验可用,但是一涉及到中文分词器,相对就比较麻烦,5.0版本暂时还没有很好的结论。

 拼写检查:可以多输入的查询条件进行纠正。  搜索关键字自动补全

 更多和搜索结果类似的结果  搜索结果聚类

因篇幅问题不能全部显示,请点此查看更多更全内容

Top