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用于文本搜索 增加各种类型的动态字段,方便扩展
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 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版本暂时还没有很好的结论。 拼写检查:可以多输入的查询条件进行纠正。 搜索关键字自动补全 更多和搜索结果类似的结果 搜索结果聚类 因篇幅问题不能全部显示,请点此查看更多更全内容