小程序文章搜索

        小程序也好,app也好,客户端还是什么乱七八糟也好,都会或多或少用到elastic search,作为一个使用海量数据的搜索引擎,吊打mysql
        有小伙伴说了,我们mysql可以分库分表,还可以做集群,还可以主从复制,但是这里有个很严重的问题,多个数据库,当要获取一定范围的·1数据时,需要去多个数据库截取数据,再汇总,这无疑麻烦而且增加了多余的开销
        这里的场景是,搜索文章,先要自定义个es索引名称,这里的索引名称就是指数据库中的表
,不管是建立索引也刚好,建立字段也好,都是通过es语句建立,类似于sql语句,至于es的安装和使用,我就不赘述了,只是说说该场景下es的使用
        首先,建立索引
 

put请求 : http://192.168.200.130:9200/app_info_article


{
    "mappings":{
        "properties":{
            "id":{
                "type":"long"
            },
            "publishTime":{
                "type":"date"
            },
            "layout":{
                "type":"integer"
            },
            "images":{
                "type":"keyword",
                "index": false
            },
            "staticUrl":{
                "type":"keyword",
                "index": false
            },
            "authorId": {
                "type": "long"
            },
            "authorName": {
                "type": "text"
            },
            "title":{
                "type":"text",
                "analyzer":"ik_smart"
            },
            "content":{
                "type":"text",
                "analyzer":"ik_smart"
            }
        }
    }
}

        关于字段的一些详细内容,我后面可能会出相关说明,但是现在,小伙伴们了解下就可以了
        然后是批量导入数据到es中,这里注意,这是一个测试类,你要在同等级的测试类中去运行

package com.heima.es;

import com.alibaba.fastjson.JSON;
import com.heima.es.mapper.ApArticleMapper;
import com.heima.es.pojo.SearchArticleVo;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.xcontent.XContentType;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.List;


@SpringBootTest
@RunWith(SpringRunner.class)
public class ApArticleTest {

    @Autowired
    private ApArticleMapper apArticleMapper;

    @Autowired
    private RestHighLevelClient restHighLevelClient;


    /**
     * 注意:数据量的导入,如果数据量过大,需要分页导入
     * @throws Exception
     */
    @Test
    public void init() throws Exception {

        //1.查询所有符合条件的文章数据
        List<SearchArticleVo> searchArticleVos = apArticleMapper.loadArticleList();

        //2.批量导入到es索引库

        BulkRequest bulkRequest = new BulkRequest("app_info_article");

        for (SearchArticleVo searchArticleVo : searchArticleVos) {

            IndexRequest indexRequest = new IndexRequest().id(searchArticleVo.getId().toString())
                    .source(JSON.toJSONString(searchArticleVo), XContentType.JSON);

            //批量添加数据
            bulkRequest.add(indexRequest);

        }
        restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);

    }

}

         接着就是完善查询数据,并作结果剖析
 

@Service
@Slf4j
@AllArgsConstructor
public class ArticleSearchServiceImpl implements ApArticleSearchService {

	private RestHighLevelClient restHighLevelClient;
	@Override
	public ResponseResult search(UserSearchDto dto) throws IOException {

		//3.结果封装返回
		List<Map> list = new ArrayList<>();

		//1.检查参数
		if (dto!=null&& StringUtils.isNotBlank(dto.getSearchWords())){
			//2.设置查询条件
			SearchRequest searchRequest = new SearchRequest("app_info_article");
			SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

			//布尔查询
			BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();

			//关键字的分词之后查询
			QueryStringQueryBuilder queryStringQueryBuilder = QueryBuilders.queryStringQuery(dto.getSearchWords()).field("title").field("content").defaultOperator(Operator.OR);
			boolQueryBuilder.filter(queryStringQueryBuilder);

			//查询小于mindate的数据
			RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("publishTime").lt(dto.getMinBehotTime().getTime());
			boolQueryBuilder.filter(rangeQueryBuilder);

			//分页查询
			searchSourceBuilder.from(0);
			searchSourceBuilder.size(dto.getPageSize());

			//按照发布时间倒序查询
			searchSourceBuilder.sort("publishTime", SortOrder.DESC);

			//设置高亮  title
			HighlightBuilder highlightBuilder = new HighlightBuilder();
			highlightBuilder.field("title");
			highlightBuilder.preTags("<font style='color: red; font-size: inherit;'>");
			highlightBuilder.postTags("</font>");
			searchSourceBuilder.highlighter(highlightBuilder);

			searchSourceBuilder.query(boolQueryBuilder);
			searchRequest.source(searchSourceBuilder);
			SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);


			//处理响应结果
			SearchHit[] hits = searchResponse.getHits().getHits();
			for (SearchHit hit : hits) {
				String json = hit.getSourceAsString();
				Map map = JSON.parseObject(json, Map.class);
				//处理高亮
				if (hit.getHighlightFields()!=null&&hit.getHighlightFields().size()>0){
					Text[] titles = hit.getHighlightFields().get("title").getFragments();
					String title = StringUtils.join(titles);
					//高亮标题
					map.put("h_title",title);
				}else {
					//原始标题
					map.put("h_title",map.get("title"));
				}
				list.add(map);
			}
		}
		return ResponseResult.okResult(list);
	}
}

        基本上就这些,然后出来的效果是这样的

        这里再问下小伙伴们

        粗粮和细糠你选谁呢
        

有什么问题欢迎大家在评论区提问,肯定回答,记得一键三连哟,每天更新 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

唐三葬PLUS

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值