Elasticsearch使用:Suggester API(二)

2021-01-26 10:34:11 浏览数 (1)

Mapping

代码语言:javascript复制
{
    "indexName":"drug",
    "indexSource":{
        "settings":{
            "number_of_shards":1,
            "number_of_replicas":2,
            "index":{
                "analysis":{
                    "filter":{
                        "bigram_filter":{
                            "max_shingle_size":"2",
                            "min_shingle_size":"2",
                            "output_unigrams":"false",
                            "type":"shingle"
                        },
                        "trigram_filter":{
                            "max_shingle_size":"3",
                            "min_shingle_size":"2",
                            "type":"shingle"
                        },
                        "my_synonym":{
                            "type":"synonym",
                            "synonyms_path":"analysis/synonym.txt"
                        }
                    },
                    "analyzer":{
                        "trigram_analyzer":{
                            "filter":[
                                "lowercase",
                                "trigram_filter"
                            ],
                            "type":"custom",
                            "tokenizer":"standard"
                        },
                        "index_ansj_analyzer":{
                            "filter":[
                                "my_synonym",
                                "asciifolding"
                            ],
                            "type":"custom",
                            "tokenizer":"index_ansj"
                        },
                        "comma":{
                            "pattern":",",
                            "type":"pattern"
                        },
                        "lowercase_ngram_1_2":{
                            "filter":"lowercase",
                            "tokenizer":"ngram_1_2_tokenizer"
                        },
                        "bigram_analyzer":{
                            "filter":[
                                "lowercase",
                                "bigram_filter"
                            ],
                            "type":"custom",
                            "tokenizer":"standard"
                        },
                        "pinyin_analyzer":{
                            "tokenizer":"my_pinyin"
                        }
                    },
                    "tokenizer":{
                        "my_pinyin":{
                            "lowercase":"true",
                            "keep_original":"false",
                            "keep_first_letter":"true",
                            "keep_separate_first_letter":"true",
                            "type":"pinyin",
                            "limit_first_letter_length":"16",
                            "keep_full_pinyin":"true",
                            "keep_none_chinese_in_joined_full_pinyin":"true",
                            "keep_joined_full_pinyin":"true"
                        },
                        "ngram_1_2_tokenizer":{
                            "token_chars":[
                                "letter",
                                "digit"
                            ],
                            "min_gram":"1",
                            "type":"nGram",
                            "max_gram":"2"
                        }
                    }
                }
            }
        },
        "mappings":{
            "properties":{
                "categoryfirst":{
                    "type":"keyword"
                },
                "categorysecond":{
                    "type":"keyword"
                },
                "commonname":{
                    "type":"completion",
                    "analyzer":"trigram_analyzer",
                    "preserve_separators":true,
                    "preserve_position_increments":true,
                    "max_input_length":50,
                    "contexts":[
                        {
                            "type":"category",
                            "name":"spu_category"
                        }
                    ],
                    "fields":{
                        "ansj":{
                            "type":"text",
                            "analyzer":"index_ansj_analyzer"
                        },
                        "text":{
                            "type":"text"
                        },
                        "pinyincompletion":{
                            "type":"completion",
                            "analyzer":"pinyin_analyzer",
                            "preserve_separators":true,
                            "preserve_position_increments":true,
                            "search_analyzer":"simple",
                            "max_input_length":50
                        },
                        "keyword":{
                            "type":"keyword"
                        },
                        "pinyin":{
                            "type":"text",
                            "boost":10,
                            "term_vector":"with_offsets",
                            "analyzer":"pinyin_analyzer"
                        },
                        "shingle":{
                            "type":"text",
                            "analyzer":"trigram_analyzer"
                        }
                    }
                },
                "ctime":{
                    "type":"date",
                    "format":"yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
                },
                "doctorteamhotid":{
                    "type":"keyword"
                },
                "drugid":{
                    "type":"keyword"
                },
                "drugname":{
                    "type":"completion",
                    "analyzer":"trigram_analyzer",
                    "preserve_separators":true,
                    "preserve_position_increments":true,
                    "max_input_length":50,
                    "contexts":[
                        {
                            "type":"category",
                            "name":"spu_category"
                        }
                    ],
                    "fields":{
                        "ansj":{
                            "type":"text",
                            "analyzer":"index_ansj_analyzer"
                        },
                        "text":{
                            "type":"text"
                        },
                        "pinyincompletion":{
                            "type":"completion",
                            "analyzer":"pinyin_analyzer",
                            "search_analyzer":"simple",
                            "preserve_separators":true,
                            "preserve_position_increments":true,
                            "max_input_length":50
                        },
                        "keyword":{
                            "type":"keyword"
                        },
                        "pinyin":{
                            "type":"text",
                            "boost":10,
                            "term_vector":"with_offsets",
                            "analyzer":"pinyin_analyzer"
                        },
                        "shingle":{
                            "type":"text",
                            "analyzer":"trigram_analyzer"
                        }
                    }
                },
                "drugtype":{
                    "type":"keyword"
                },
                "factoryname":{
                    "type":"text",
                    "fields":{
                        "ansj":{
                            "type":"text",
                            "analyzer":"index_ansj_analyzer"
                        },
                        "keyword":{
                            "type":"keyword"
                        },
                        "pinyin":{
                            "type":"text",
                            "boost":10,
                            "term_vector":"with_offsets",
                            "analyzer":"pinyin_analyzer"
                        },
                        "shingle":{
                            "type":"text",
                            "analyzer":"trigram_analyzer"
                        }
                    },
                    "copy_to":[
                        "text_all"
                    ]
                },
                "id":{
                    "type":"keyword"
                },
                "included":{
                    "type":"keyword"
                },
                "indextype":{
                    "type":"keyword"
                },
                "iscfda":{
                    "type":"keyword"
                },
                "medicineaccuratenum":{
                    "type":"keyword",
                    "copy_to":[
                        "text_all"
                    ]
                },
                "prescription":{
                    "type":"keyword"
                },
                "stock":{
                    "type":"long"
                },
                "relation":{
                    "type":"join",
                    "eager_global_ordinals":true,
                    "relations":{
                        "drug-spu":[
                            "drug-doctorteamhot",
                            "drug-sku"
                        ]
                    }
                },
                "text_all":{
                    "type":"text"
                },
                "utime":{
                    "type":"date",
                    "format":"yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
                }
            }
        }
    }
}

API

代码语言:javascript复制
public Map<String, List> termSuggestDrug(DrugSearchRequest searchRequest) {

    String keyword = searchRequest.getKeyword();

    SearchSourceBuilder builder = new SearchSourceBuilder();

    if (StringUtils.isNotBlank(keyword)) {
        SuggestionBuilder drugnameTermSuggestionBuilder = SuggestBuilders.termSuggestion("commonname.ansj")
                .text(keyword)
                .maxEdits(2)
                .minWordLength(2)
                .suggestMode(TermSuggestionBuilder.SuggestMode.ALWAYS)
                .prefixLength(2)
                .analyzer("simple")
                .size(10);
        SuggestBuilder suggestBuilder = new SuggestBuilder();
        suggestBuilder.addSuggestion("termSuggest", drugnameTermSuggestionBuilder);
        builder.suggest(suggestBuilder);
    }

    log.info(SearchConst.BUILDER_DATA, builder);
    LocalLogger.builder("termSuggestDrug")
            .string1(builder.toString())
            .string2(gson.toJson(searchRequest))
            .string3(TraceHelper.getUniqueKey())
            .time1(new HaoDate())
            .info();

    SearchResponse result = searchDao.searchBySearchSourceBuilder(builder, INDEX_NAME);

    Map<String, List> resultResponse = Maps.newHashMap();

    List<Map<String,Object>> hits = Lists.newArrayList();
    if (null != result) {
        Iterator<SearchHit> iterator = result.getHits().iterator();
        while (iterator.hasNext()) {
            Map<String, Object> hit = new HashMap<>();
            SearchHit searchHit = iterator.next();

            hit.put("matches", searchHit.getSourceAsMap());
            hit.put("score", searchHit.getScore());

            hits.add(hit);
        }

        Suggest suggest = result.getSuggest();
        Iterator suggestionIterator = suggest.iterator();
        TermSuggestion termSuggestion;
        while (suggestionIterator.hasNext()) {
            termSuggestion = (TermSuggestion)suggestionIterator.next();
            List suggestions = Lists.newArrayList();
            String name = termSuggestion.getName();
            for (TermSuggestion.Entry entry : termSuggestion){
                for (TermSuggestion.Entry.Option option : entry){
                    Map<String, Object> optionMap = Maps.newHashMap();
                    String text = option.getText().string();
                    float score = option.getScore();

                    optionMap.put("text", text);
                    optionMap.put("score", score);

                    suggestions.add(optionMap);
                }
            }
            resultResponse.put(name, suggestions);
        }
    }
    resultResponse.put("hits", hits);
    return resultResponse;
}

public Map<String, List> phraseSuggestDrug(DrugSearchRequest searchRequest) {

    String keyword = searchRequest.getKeyword();

    SearchSourceBuilder builder = new SearchSourceBuilder();

    if (StringUtils.isNotBlank(keyword)) {
        PhraseSuggestionBuilder drugnameSuggestBuilder = SuggestBuilders.phraseSuggestion("commonname.ansj")
                .text(keyword)
                .highlight("<em>", "</em>")
                .maxErrors(2) // 最多可以拼错的 Terms 数
                .analyzer("simple")
                .confidence(0)
                .size(10);

        SuggestBuilder suggestBuilder = new SuggestBuilder();
        suggestBuilder.addSuggestion("phraseSuggest", drugnameSuggestBuilder);
        builder.suggest(suggestBuilder);
    }

    log.info(SearchConst.BUILDER_DATA, builder);
    LocalLogger.builder("phraseSuggestDrug")
            .string1(builder.toString())
            .string2(gson.toJson(searchRequest))
            .string3(TraceHelper.getUniqueKey())
            .time1(new HaoDate())
            .info();

    SearchResponse result = searchDao.searchBySearchSourceBuilder(builder, INDEX_NAME);

    Map<String, List> resultResponse = Maps.newHashMap();

    List<Map<String,Object>> hits = Lists.newArrayList();
    if (null != result) {

        Iterator<SearchHit> iterator = result.getHits().iterator();
        while (iterator.hasNext()) {
            Map<String, Object> hit = new HashMap<>();
            SearchHit searchHit = iterator.next();

            hit.put("matches", searchHit.getSourceAsMap());
            hit.put("score", searchHit.getScore());

            hits.add(hit);
        }

        Suggest suggest = result.getSuggest();
        Iterator suggestionIterator = suggest.iterator();
        PhraseSuggestion phraseSuggestion;
        while (suggestionIterator.hasNext()) {
            phraseSuggestion = (PhraseSuggestion)suggestionIterator.next();
            List suggestions = Lists.newArrayList();
            String name = phraseSuggestion.getName();
            for (PhraseSuggestion.Entry entry : phraseSuggestion){
                for (PhraseSuggestion.Entry.Option option : entry){
                    Map<String, Object> optionMap = Maps.newHashMap();
                    String text = option.getText().string();
                    float score = option.getScore();
                    String highlighted =  option.getHighlighted().string();

                    optionMap.put("text", text);
                    optionMap.put("score", score);
                    optionMap.put("highlighted", highlighted);

                    suggestions.add(optionMap);
                }
            }
            resultResponse.put(name, suggestions);
        }
    }
    resultResponse.put("hits", hits);
    return resultResponse;
}

public Set completionSuggestDrug(DrugSearchRequest searchRequest) {

    String keyword = searchRequest.getKeyword();
    String category = searchRequest.getCategory();

    SearchSourceBuilder builder = new SearchSourceBuilder();
    if (StringUtils.isNotBlank(keyword)) {

        CompletionSuggestionBuilder commonnameBuilder = SuggestBuilders.completionSuggestion("commonname")
                .prefix(keyword).skipDuplicates(true)
                .size(10);

        CompletionSuggestionBuilder drugnameBuilder = SuggestBuilders.completionSuggestion("drugname")
                .prefix(keyword).skipDuplicates(true)
                .size(10);
        SuggestionBuilder pinyinDrugnameBuilder = SuggestBuilders.completionSuggestion("drugname.pinyincompletion")
                .prefix(keyword).skipDuplicates(true)
                .size(10);
        SuggestionBuilder pinyinCommonnameBuilder = SuggestBuilders.completionSuggestion("commonname.pinyincompletion")
                .prefix(keyword).skipDuplicates(true)
                .size(10);

        if (StringUtils.isNotBlank(category)) {

            CategoryQueryContext context = CategoryQueryContext.builder()
                    .setBoost(1)
                    .setCategory(category)
                    .setPrefix(false).build();
            Map categoryMap = Maps.newHashMap();
            List categoryList = Lists.newArrayList();
            categoryList.add(context);
            categoryMap.put("spu_category", categoryList);

            commonnameBuilder.contexts(categoryMap);
            drugnameBuilder.contexts(categoryMap);
        }

        String[] source = {"commonname", "drugname"};
        SuggestBuilder suggestBuilder = new SuggestBuilder();
        suggestBuilder.addSuggestion("commonname-completionsuggest", commonnameBuilder)
                .addSuggestion("drugname-completionsuggest", drugnameBuilder)
                .addSuggestion("pinyincommonvame-completionsuggest", pinyinCommonnameBuilder)
                .addSuggestion("pinyindrugname-completionsuggest", pinyinDrugnameBuilder);
        builder.suggest(suggestBuilder).fetchSource(source, null);
    }

    log.info(SearchConst.BUILDER_DATA, builder);
    LocalLogger.builder("completionSuggestDrug")
            .string1(builder.toString())
            .string2(gson.toJson(searchRequest))
            .string3(TraceHelper.getUniqueKey())
            .time1(new HaoDate())
            .info();

    SearchResponse result = searchDao.searchBySearchSourceBuilder(builder, INDEX_NAME);

    Set hits = Sets.newHashSet();
    if (null != result) {

        Suggest suggest = result.getSuggest();
        Iterator suggestionIterator = suggest.iterator();
        CompletionSuggestion completionSuggestion;
        while (suggestionIterator.hasNext()) {
            completionSuggestion = (CompletionSuggestion)suggestionIterator.next();
            for (CompletionSuggestion.Entry entry : completionSuggestion){
                for (CompletionSuggestion.Entry.Option option : entry){
                    String text = option.getText().string();

                    hits.add(text);
                }
            }
        }
    }
    return hits;
}

0 人点赞