2

I was able to search by whole words, for example searching phrase "secret" text "This is a secret word" was found. But If I search for phrase "secre" I get an empty array. I need this for autocomplete function. I'm using Spring Boot release 1.3.1.RELEASE (it uses Elasticsearch version 1.5.2 and I can't upgrade spring). What am I doing wrong? I'l be thankful for a link to a working example also. I know Elasticsearch is too heavy for this purpose but I want to learn how to use it. Many thanks in advance!

SearchConfig.java

@Configuration
@EnableElasticsearchRepositories(basePackages = {"cz.project.search"})
public class SearchConfig {

    @Autowired
    private Client elasticsearchClient;

    @Bean
    public ConstructionWorkIndexInitializer constructionWorkIndexInitializer() {
        return new ConstructionWorkIndexInitializer();
    }
}

ConstructionWorkIndexRepository.java

public interface ConstructionWorkIndexRepository extends ElasticsearchRepository<ConstructionWorkIndex, String> {
        Page<ConstructionWorkIndex> findByCodeOrDescription(String code, String description, Pageable pageable);
}

ConstructionWorkIndex.java

@Data
@AllArgsConstructor
@NoArgsConstructor
@Document(indexName = "works", type = "work", shards = 1, replicas = 0, indexStoreType = "memory", refreshInterval = "-1")
@Setting(settingPath = "classpath:construction-works-settings.json")
public class ConstructionWorkIndex {

    @Id
    @Field(indexAnalyzer = "standard", searchAnalyzer = "standard", type = FieldType.String, store = true)
    private String code;

    @Field(indexAnalyzer = "standard", searchAnalyzer = "standard", type = FieldType.String, store = true)
    private String description;

    public ConstructionWorkIndex(ConstructionWorkVO constructionWork) {
        requireNonNull(constructionWork, "constructionWork must not be null");
        this.code = constructionWork.getCode();
        this.description = constructionWork.getDescription();
    }
}

construction-works-settings.json

{
  "filter": {
    "autocomplete_filter": {
      "type": "edge_ngram",
      "min_gram": 1,
      "max_gram": 20
    }
  },
  "analyzer": {
    "autocomplete": {
      "type": "custom",
      "tokenizer": "standard",
      "filter": [
        "lowercase",
        "autocomplete_filter"
      ]
    }
  }
}

ConstructionWorkIndexInitializer.java

@Slf4j
public class ConstructionWorkIndexInitializer {

    @Autowired
    private ConstructionWorkRepository workRepository;

    @Autowired
    private ConstructionWorkIndexRepository workIndexRepository;

    @PostConstruct
    @Transactional(readOnly = true)
    @Async
    public void init() {
        initWorks();
    }

    private void initWorks() {
        List<ConstructionWorkVO> works = workRepository.findAll();
        works.forEach(work -> {
            workIndexRepository.save(new ConstructionWorkIndex(work));
            log.debug("Added construction work code '{}'", work.getCode());
        });
        log.debug("Indexed {} construction works", works.size());
    }
}
Vojtech
  • 2,533
  • 9
  • 34
  • 65
  • You're defining the `autocomplete` analyzer but you're not using it. Have you tried to change `indexAnalyzer = "standard"` to `indexAnalyzer = "autocomplete"`? – Val Mar 14 '17 at 04:30
  • @Val Unfortunately it doesn't work. I'm getting error "ERROR o.s.d.e.r.s.AbstractElasticsearchRepository - failed to load elasticsearch nodes : org.elasticsearch.index.mapper.MapperParsingException: Analyzer [autocomplete] not found for field [description]". – Vojtech Mar 14 '17 at 10:14
  • Your settings file is not well-formed. See this answer on how it should look like: http://stackoverflow.com/a/38559521/4604579 – Val Mar 15 '17 at 05:03
  • Thanks, it seems to work! Write an answer so that I can accept it. – Vojtech Apr 25 '17 at 15:17
  • Cool, you can upvote the answer I've referenced ;-) – Val Apr 25 '17 at 15:24

0 Answers0