09solr

it2022-05-05  164

solr是一个开源搜索平台  它是基于Lucene的全文搜索服务器特点  比关系型数据库搜索速度要快  关系型数据库只能进行模糊查询 低效 数据库压力大 所以用solr做搜索功能solr本身是在tomcat环境下运行solr下的 /example/solr目录就是solr的家  将solr改名为solrhome  关联solr和solrhome 需要修改 solr工程的web.xml  设置solrhome的路径位置

 <env-entry>

       <env-entry-name>solr/home</env-entry-name>

       <env-entry-value>d:\solrhome</env-entry-value>

       <env-entry-type>java.lang.String</env-entry-type>

    </env-entry>输入http://IP:8080/solr/就可以访问solr了 IK Analyzer  中文分词工具包在solr工程的lib中添加分词器的jar包solr工程中创建 WEB-INF/calsses文件夹  放上1扩展词典  以.dic结尾  2 停用词典 以.dic结尾, 配置文件(设置1,2的位置)修改solrhome中的schema.xml文件配置一个fieldType  使用Ik分词器 <fieldType name="text_ik" class="solr.TextField"> <analyzer class="org.wltea.analyzer.lucene.IKAnalyzer"/> </fieldType>

 

配置域   域相当于数据库中的表字段

域常用属性 

name 指定域名称

type指定域类型  (可以设置成中文分词器filedType的名字  text_ik)就可以进行中文分词效果了

indexed是否进行索引 即根据这个字段查询

stored是否进行存储

required是否必须

multiValue是否多值

修改solrhome的schema.xml 文件  设置业务系统 Field

<field name="item_goodsid" type="long" indexed="true" stored="true"/> <field name="item_title" type="text_ik" indexed="true" stored="true"/> <field name="item_price" type="double" indexed="true" stored="true"/> <field name="item_image" type="string" indexed="false" stored="true" /> <field name="item_category" type="string" indexed="true" stored="true" /> <field name="item_seller" type="text_ik" indexed="true" stored="true" /> <field name="item_brand" type="string" indexed="true" stored="true" />

 

动态域<dynamicField name="item_spec_*" type="string" indexed="true" stored="true" />    复制域    source原目标域, dest 复制域的名称 当需要进行多条件查询时不确定是按那个条件查询就可以设置复制域

<field name="item_keywords" type="text_ik" indexed="true" stored="false" multiValued="true"/>

<copyField source="item_title" dest="item_keywords"/> 商品标题

<copyField source="item_category" dest="item_keywords"/>商品分类

<copyField source="item_brand" dest="item_keywords"/>商品品牌src/main/resources下创建  applicationContext-solr.xml   配置 solr服务器地址 和 solrTemplate模板,使用solr模板可对索引库进行CRUD的操作 如果 pojo实体类中的属性名称和solr配置域中名称不相同则应在pojo属性上加@Field(“item_id”)指定对应的域名称保存数据到solr中可以添加注解  @Autowired  private SolrTemplate  solrTemplate solrTemplate.saveBean(User) solrTemplate.commit()

 

按主键查询  User user=solrTemplate.getById(id值,User.class)按主键删除 solr.deleteById("id值")条件查询  Query query =new SimpleQuery("*:*")开始索引  query.setOffset(20)   solr默认是从0开始每页记录数query.setRows(20)分页查询 ScoredPage page= solrTemplate.queryForPage(query,User.class)获得总记录数  page.getTotalElements()获取查询内容  page.getContent()  Query query=new SimpleQuery("*:*"); query.setOffset(20);//开始索引(默认0) query.setRows(20);//每页记录数(默认10) ScoredPage<TbItem> page = solrTemplate.queryForPage(query, TbItem.class); System.out.println("总记录数:"+page.getTotalElements()); List<TbItem> list = page.getContent();

 

条件查询 solr自带的 Criteria  criteria =new Criteria("tb_username").is("张三")  查询用户名就是张三的继续查询密码包含aa的 criteria.and("tb_password").contains("aa")  

 

控制层调用服务层时避免超时  应加@Reference(timeout=5000)

项目中在后端服务层使用Map接收数据  返回键名为rows 的数据

@Override public Map<String, Object> search(Map searchMap) { Map<String,Object> map=new HashMap<>(); Query query=new SimpleQuery(); //添加查询条件 Criteria criteria=new Criteria("item_keywords").is(searchMap.get("keywords")); query.addCriteria(criteria); ScoredPage<TbItem> page = solrTemplate.queryForPage(query, TbItem.class); map.put("rows", page.getContent()); return map; } }

pinyougou-search-web工程searchController.js

app.controller('searchController',function($scope,searchService){  

    //搜索

    $scope.search=function(){

        searchService.search( $scope.searchMap ).success(

            function(response){                    

                $scope.resultMap=response;//搜索返回的结果

            }

        ); 

    }  

});

前端页面

 ng-model="searchMap.keywords"  传给后端的map中的key叫keywords  值为页面输入的值

ng-repeat="aa in resultMap.rows"  循环后端传回来的数据键名rows  就可以取出数据

高亮显示 后端service层HighlightQuery  query =new SimpleHighlightQuery();添加高亮选项HighlightOptions options=new HighlightOptions().addField("item_title")添加前缀 options.setSimplePrefix()  后缀  options.setSimplePostfix()solrTemplate.queryForHighlightPage(query,TbItem.class) /** * 根据关键字搜索列表 * @param keywords * @return */ private Map searchList(Map searchMap){ Map map=new HashMap(); HighlightQuery query=new SimpleHighlightQuery(); HighlightOptions highlightOptions=new HighlightOptions().addField("item_title");//设置高亮的域 highlightOptions.setSimplePrefix("<em style='color:red'>");//高亮前缀 highlightOptions.setSimplePostfix("</em>");//高亮后缀 query.setHighlightOptions(highlightOptions);//设置高亮选项 //按照关键字查询 Criteria criteria=new Criteria("item_keywords").is(searchMap.get("keywords")); query.addCriteria(criteria); HighlightPage<TbItem> page = solrTemplate.queryForHighlightPage(query, TbItem.class); for(HighlightEntry<TbItem> h: page.getHighlighted()){//循环高亮入口集合 TbItem item = h.getEntity();//获取原实体类 if(h.getHighlights().size()>0 && h.getHighlights().get(0).getSnipplets().size()>0){ item.setTitle(h.getHighlights().get(0).getSnipplets().get(0));//设置高亮的结果 } } map.put("rows",page.getContent()); return map; }

 

js中设置消除安全机制设置过滤器  中添加  $sce.trustAsHtml(data)

/*$sce服务写成过滤器*/

app.filter('aa',['$sce',function($sce){

    return function(data){

        return $sce.trustAsHtml(data);

    }

}]);

html页面  ng-bind-html用于显示html内容  在此显示color标签 

代表调用过滤器aa  

<div class="attr" ng-bind-html="item.title | aa"></div>

 

按价格区间过滤 前端key='price" value为价格值后端 根据price键获取值  String [] price=aa.get("price").split("-")FilterQuery query=new SimpleFilterQuery()Criteria filterCriteria=new Criteria("item-price").graterThanEqual(price[0])价格排序  后端根据前端点击  判断 升序  Sort sort =new Sort(Sort.Direction.ASC,"item_price")降序 Sort sort =new Sort(Sort.Direction.DESC,"item_price") query.add(sort)@Field  注解匹配实体类和solr数据库中名称不同  是solrj包下的搜索项目分析   通过search方法  参数是map类型  参数返回值是map类型,添加条件通过solr配置域中复制域来查询Criteria criteria =new Criteria("item_keywords").is(map.get("key"));===========================商品分类  通过 solrTemplate.queryForGroupPage() 进行分组查询通过商品分类到商品分类表中查找对应的品牌关联表    品牌表  商品表  商品分类表商品分类表 item_cate  中有品牌表的id整体思路  前台搜索框中点击事件根据关键字进行搜索的时候 通过复制域可以查询带有关键字的商品标题商品品牌商品分类的高亮数据 并通过solrTemplate的分组查询,根据商品分类域查询出商品分类,。通过根据商品分类查询出对应的品牌,显示商品分类  和品牌的数据供用户进行筛选,用户选择条件时则   ,当用户选择商品分类或者品牌时,根据solrTemplate的过滤查询查询出对应的结果根据关键字查询以商品分类为分组的数据    使用  GroupOptions.addGroupByField("商品分类域名")即在qurey条件上加addGroupByField()SolrTemplate.queryForGroupPage()以价格进行查询在前端有searchMap对象用于封装搜索条件从首页跳转到搜索页  使用  #?在搜索页进行接收 先在前端controller上加$location 

 

 

 

 

 


最新回复(0)