[solr] - Facet - autocomplete
Solr的facet可以用于一般性的前缀式自动完成功能,当然,它的主要功能是用于做统计、分类、区间等。
统计、分类、区间功能,可参考下文:
http://hongweiyi.com/2013/03/apache-solr-facet-introduction/
下面例子是使用Facet做前缀式自动完成功能。
schema.xml
<?xml version="1.0" ?> <schema name="my core" 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="tdate" class="solr.TrieDateField" precisionStep="6" positionIncrementGap="0"/> <fieldType name="int" class="solr.TrieIntField" precisionStep="0" positionIncrementGap="0"/> <fieldType name="float" class="solr.TrieFloatField" precisionStep="0" positionIncrementGap="0"/> <fieldType name="double" class="solr.TrieDoubleField" precisionStep="0" positionIncrementGap="0"/> <fieldType name="boolean" class="solr.BoolField" sortMissingLast="true"/> <fieldtype name="binary" class="solr.BinaryField"/> <fieldType name="text_cn" class="solr.TextField"> <analyzer type="index" class="org.wltea.analyzer.lucene.IKAnalyzer" /> <analyzer type="query" class="org.wltea.analyzer.lucene.IKAnalyzer" /> </fieldType> <!-- general --> <field name="id" type="long" indexed="true" stored="true" multiValued="false" required="true"/> <field name="subject" type="text_cn" indexed="true" stored="true" /> <field name="content" type="text_cn" indexed="true" stored="true" /> <field name="category_id" type="long" indexed="true" stored="true" /> <field name="category_name" type="text_cn" indexed="true" stored="true" /> <field name="last_update_time" type="tdate" 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>subject</defaultSearchField> <!-- SolrQueryParser configuration: defaultOperator="AND|OR" --> <solrQueryParser defaultOperator="OR"/> </schema>
Java Bean:
package com.my.entity; import java.util.Date; import org.apache.solr.client.solrj.beans.Field; public class Item { @Field private long id; @Field private String subject; @Field private String content; @Field("category_id") private long categoryId; @Field("category_name") private String categoryName; @Field("last_update_time") private Date lastUpdateTime; public long getId() { return id; } public void setId(long id) { this.id = id; } public String getSubject() { return subject; } public void setSubject(String subject) { this.subject = subject; } public String getContent() { return content; } public void setContent(String content) { this.content = content; } public long getCategoryId() { return categoryId; } public void setCategoryId(long categoryId) { this.categoryId = categoryId; } public String getCategoryName() { return categoryName; } public void setCategoryName(String categoryName) { this.categoryName = categoryName; } public Date getLastUpdateTime() { return lastUpdateTime; } public void setLastUpdateTime(Date lastUpdateTime) { this.lastUpdateTime = lastUpdateTime; } }
测试:
package com.my.solr; import java.io.IOException; import java.util.ArrayList; import java.util.Date; import java.util.List; import org.apache.solr.client.solrj.SolrQuery; import org.apache.solr.client.solrj.SolrQuery.ORDER; import org.apache.solr.client.solrj.SolrQuery.SortClause; import org.apache.solr.client.solrj.SolrServerException; import org.apache.solr.client.solrj.impl.HttpSolrServer; import org.apache.solr.client.solrj.impl.XMLResponseParser; import org.apache.solr.client.solrj.response.FacetField; import org.apache.solr.client.solrj.response.FacetField.Count; import org.apache.solr.client.solrj.response.QueryResponse; import com.my.entity.Item; public class TestSolr { public static void main(String[] args) throws IOException, SolrServerException { String url = "http://localhost:8899/solr/mycore"; HttpSolrServer core = new HttpSolrServer(url); core.setMaxRetries(1); core.setConnectionTimeout(5000); core.setParser(new XMLResponseParser()); // binary parser is used by default core.setSoTimeout(1000); // socket read timeout core.setDefaultMaxConnectionsPerHost(100); core.setMaxTotalConnections(100); core.setFollowRedirects(false); // defaults to false core.setAllowCompression(true); // ------------------------------------------------------ // remove all data // ------------------------------------------------------ core.deleteByQuery("*:*"); List<Item> items = new ArrayList<Item>(); items.add(makeItem(1, "cpu", "this is intel cpu", 1, "cpu-intel")); items.add(makeItem(2, "cpu AMD", "this is AMD cpu", 2, "cpu-AMD")); items.add(makeItem(3, "cpu intel", "this is intel-I7 cpu", 1, "cpu-intel")); items.add(makeItem(4, "cpu AMD", "this is AMD 5000x cpu", 2, "cpu-AMD")); items.add(makeItem(5, "cpu intel I6", "this is intel-I6 cpu", 1, "cpu-intel-I6")); core.addBeans(items); // commit core.commit(); // ------------------------------------------------------ // search // ------------------------------------------------------ SolrQuery query = new SolrQuery(); query.setQuery("*:*"); query.setStart(0); // query的开始行数(分页使用) query.setRows(0); // query的返回行数(分页使用) query.setFacet(true); // 设置使用facet query.setFacetMinCount(1); // 设置facet最少的统计数量 query.setFacetLimit(10); // facet结果的返回行数 query.addFacetField("category_name"); // facet的字段 query.setFacetPrefix("cpu"); // facet字段值 query.addSort(new SortClause("id", ORDER.asc)); // 排序 QueryResponse response = core.query(query); List<Item> items_rep = response.getBeans(Item.class); List<FacetField> facetFields = response.getFacetFields(); // 因为上面的start和rows均设置为0,所以这里不会有query结果输出 for (Item i : items_rep) { System.out.println("id=" + i.getId() + "\tcontent=" + i.getContent()); } // 打印所有facet for(FacetField ff : facetFields) { System.out.println("name=" + ff.getName() + "\tcount=" + ff.getValueCount()); System.out.println("--------------------"); for(Count count: ff.getValues() ) { System.out.println("name=" + count.getName() + "\tvalue=" + count.getCount()); } } } private static Item makeItem(long id, String subject, String content, long categoryId, String categoryName) { Item item = new Item(); item.setId(id); item.setSubject(subject); item.setContent(content); item.setLastUpdateTime(new Date()); item.setCategoryId(categoryId); item.setCategoryName(categoryName); return item; } }
输出结果: