springboot集成Elasticsearch实现关键字补全

环境准备:
Elasticsearch服务器
ik中文分词器
Kibana服务
一个集成了ES的springboot项目

博主环境:
es:6.2.2 Kibana:6.2.2 springboot:2.1.2

实现目标:建立学生数据索引,以学生姓名为搜索自动补全字段。
学生实体类:

@Document(indexName = "student_index",type="student")
public class Student implements Serializable {
    @Id
    @Field(type= FieldType.Auto)
    private String studentId;

    @Override
    public String toString() {
        return "Student{" +
                "studentId='" + studentId + '\'' +
                ", name='" + name + '\'' +
                ", age=" + age +
                ", scores=" + scores +
                '}';
    }

    public Student(String studentId, String name, Integer age, List<Double> scores) {
        this.studentId = studentId;
        this.name = name;
        this.age = age;
        this.scores = scores;
    }

    public Student() {

    }

    public String getStudentId() {

        return studentId;
    }

    public void setStudentId(String studentId) {
        this.studentId = studentId;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public List<Double> getScores() {
        return scores;
    }

    public void setScores(List<Double> scores) {
        this.scores = scores;
    }

    @Field(type=FieldType.Auto)
    private String name;

    @Field(type=FieldType.Auto)
    private Integer age;

    @Field(type=FieldType.Auto)
    private List<Double> scores;
}

建立学生的索引和映射:
待搜索的字段需要设置为Completion类型

PUT /student_index
{

  "mappings": {

    "student" : {

      "properties" : {

        "name" : {

          "type" :    "completion",

          "analyzer": "ik_smart"

        },

        "age" : {

          "type" :   "integer"

        },

       
        "studentId" : {

          "type" :   "text"

        },
        
        "scores":{
          "type" :  "float"
          
        }       

      }

    }

  }

}

整点数据测试一下:

学生索引Repository类:

@Repository
public interface StudentRepository extends ElasticsearchCrudRepository<Student,String>{
}

开始测试:
在程序里插入一些数据;

@Autowired
	private ElasticsearchTemplate elasticsearchTemplate;
	@Test
	public void contextLoads() {

		List scores= new ArrayList<>();
		scores.add(67.2);
		scores.add(27.2);
		scores.add(56.2);

/*		studentIndexRepository.save(new Student(UUID.randomUUID().toString(), "张三", 21, scores ));
		studentIndexRepository.save(new Student(UUID.randomUUID().toString(), "李四", 35, scores ));
		studentIndexRepository.save(new Student(UUID.randomUUID().toString(), "王二", 45, scores ));
		studentIndexRepository.save(new Student(UUID.randomUUID().toString(), "张大林", 23, scores ));
		studentIndexRepository.save(new Student(UUID.randomUUID().toString(), "王大力", 51, scores ));*/

		studentIndexRepository.save(new Student(UUID.randomUUID().toString(), "刘伯", 21, scores ));
		studentIndexRepository.save(new Student(UUID.randomUUID().toString(), "刘思想", 35, scores ));
		studentIndexRepository.save(new Student(UUID.randomUUID().toString(), "王皮皮", 45, scores ));
		studentIndexRepository.save(new Student(UUID.randomUUID().toString(), "王二丫", 23, scores ));
		studentIndexRepository.save(new Student(UUID.randomUUID().toString(), "王铁蛋", 51, scores ));
	}

在Kibana测试

POST /student_index/completion/_search
{ "size": 0,
  "suggest": {
    "name-suggest": {
      "prefix": "王二",
      "completion": {
        "field": "name"
      }
    }
  }
}

结果正确:
在这里插入图片描述
接下来是实现获取suggest的代码:

	@Test
	public void testSuggestCompletionProc() {

		String suggestField="name";//指定在哪个字段搜索
		String suggestValue="王二";//输入的信息
		Integer suggestMaxCount=10;//获得最大suggest条数

		CompletionSuggestionBuilder suggestionBuilderDistrict = new CompletionSuggestionBuilder(suggestField).prefix(suggestValue).size(suggestMaxCount);
		SuggestBuilder suggestBuilder = new SuggestBuilder();
		suggestBuilder.addSuggestion("student_suggest", suggestionBuilderDistrict);//添加suggest

		//设置查询builder的index,type,以及建议
		SearchRequestBuilder requestBuilder = this.elasticsearchTemplate.getClient().prepareSearch("student_index").setTypes("student").suggest(suggestBuilder);
		System.out.println(requestBuilder.toString());

		SearchResponse response = requestBuilder.get();
		Suggest suggest = response.getSuggest();//suggest实体

		Set<String> suggestSet = new HashSet<>();//set
		int maxSuggest = 0;
		if (suggest != null) {
			Suggest.Suggestion result = suggest.getSuggestion("student_suggest");//获取suggest,name任意string
			for (Object term : result.getEntries()) {

				if (term instanceof CompletionSuggestion.Entry) {
					CompletionSuggestion.Entry item = (CompletionSuggestion.Entry) term;
					if (!item.getOptions().isEmpty()) {
						//若item的option不为空,循环遍历
						for (CompletionSuggestion.Entry.Option option : item.getOptions()) {
							String tip = option.getText().toString();
							if (!suggestSet.contains(tip)) {
								suggestSet.add(tip);
								++maxSuggest;
							}
						}
					}
				}
				if (maxSuggest >= suggestMaxCount) {
					break;
				}
			}
		}

		List<String> suggests = Arrays.asList(suggestSet.toArray(new String[]{}));

		suggests.forEach((s)->{
			System.out.println(s);
		});

//		return	 suggests;

	}

输出结果正确:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/wangxudongx/article/details/87275232