Как читать документы изasticsearch с помощью Spring Data? - PullRequest
0 голосов
/ 29 октября 2018

Я создал индекс (дом) с типом «квартиры», который содержит 20 документов. Я загрузил Json в виде двоичного файла вasticsearch с помощью почтальона. У меня есть проект Spring Boot, который имеет следующие классы:

  1. EsConfig.java - Я настроил имя кластера, которое является именем по умолчанию в файле application.properties.

    @Configuration
    @EnableElasticsearchRepositories(basePackages = "com.search.repository")
    public class EsConfig {
    
    @Value("${elasticsearch.clustername}")
    private String EsClusterName;
    
    @Bean
    public Client esClient() throws UnknownHostException {
        Settings esSettings = Settings.builder()
                .put("cluster.name", EsClusterName)
                .put("client.transport.sniff", true)
                .put("client.transport.ignore_cluster_name", false)
                .build();
    
    
       TransportClient  client = new PreBuiltTransportClient(esSettings)
        .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("localhost"), 9300));
        return client;
    
    }
    
    @Bean
    public ElasticsearchOperations elasticsearchTemplate() throws Exception{
        return new ElasticsearchTemplate(esClient()); 
      }
    }
    
  2. Apartments.java - Это моя модель данных. Документы имеют следующие поля вasticsearch.

    @Document(indexName = "house", type = "apartments")
    @JsonIgnoreProperties(ignoreUnknown=true)
    public class Apartments {
    
       @Id
       private String id;
       @JsonProperty("Apartment_Name")
       private String apartmentName;
       @JsonProperty("Apartment_ID")
       private String apartmentId;
       @JsonProperty("Area_Name")
       private String areaName;
    
       //constructors along with getters and setters
    }
    
  3. ApartmentSearchRepository.java - это интерфейс, расширяющий интерфейс ElasticsearchRepository для выполнения операций crud.

    public interface ApartmentSearchRepository extends ElasticsearchRepository<Apartments, String> {
    List<Apartments> findByApartmentName(String apartmentName);
    }
    
  4. EsApartmentService.java -

    @Service
    public class EsApartmentService {
    
    @Autowired
    ApartmentSearchRepository apartmentSearchRepository;
    
    public List<Apartments> getApartmentByName(String apartmentName) {
        return apartmentSearchRepository.findByApartmentName(apartmentName);
       }
    }
    
  5. ApartmentController.java - Я создал конечную точку, которая должна возвращать эти 20 документов изasticsearch. (Кроме того, Apartment - это POJO в моем проекте, а Apartments - модель данных.)

    @Autowired
    EsApartmentService esApartmentService;
    @GetMapping(path = "/search",produces = "application/json")
    public Set<Apartment> searchApartmentByName(
      @RequestParam(value = "apartmentName", defaultValue = "") String apartmentName) throws IOException {
      List<Apartment> apartments= new ArrayList<>();
      esApartmentService.getApartmentByName(apartmentName).forEach(apartment-> {
            apartments.add(new Apartment(apartment.getApartmentName(), apartment.getApartmentId(), apartment.getAreaName()));
        });
      return apartments.stream()
              .collect(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(Apartment::getApartmentId))));
    }
    

Этот код возвращает статус 200, но с пустым ответом. Я попытался отладить, но кажется, что он не может прочитать эти документы из эластичного поиска. Я прошел через несколько решений, но большинство из них установили данные документа в самом коде.

Я не могу получить эти документы, нажав конечную точку, указанную в контроллере. Может ли кто-нибудь дать мне знать, что я могу упустить? Спасибо! :)

Редактировать: На снимке экрана ниже показаны запрос и ответ в Почтальоне. enter image description here

Ответы [ 2 ]

0 голосов
/ 30 октября 2018

Как упомянуто выше @ibexit, я удалил @JsonProperty и использовал встроенный построитель поисковых запросов в моем сервисе. Кроме того, он не брал Apartment_Name и работал, когда я дал apartment_Name. (похоже, у Elasticsearch есть проблемы с делом, поэтому я дал его в случае с верблюдом.)

Мои изменения:

  1. Apartments.java - Удалено @ JsonProperty

    @Document(indexName = "house", type = "apartments")
    //@JsonIgnoreProperties(ignoreUnknown=true)
    public class Apartments {
    
     @Id
     private String id;
    
     //@JsonProperty("apartment_ID")
     private String apartment_ID;
    
     //@JsonProperty("Area_Name")
     private String area_Name;
    
     //@JsonProperty("Apartment_Name")
     private String apartment_Name;
    }
    
  2. EsApartmentService.java -

    @Service
    public class EsApartmentService {
    @Autowired
    private  ElasticsearchTemplate elasticsearchTemplate; 
    
    public List<Apartments> getApartmentByName(String apartmentName) {
       SearchQuery searchQuery = new NativeSearchQueryBuilder()           
      .withQuery(org.elasticsearch.index.query.QueryBuilders
        .matchQuery("apartment_Name", apartmentName)).build();
    Page<Apartments> sampleEntities = 
        elasticsearchTemplate.queryForPage(searchQuery,Apartments.class);      
    return sampleEntities.getContent();
      }
    }
    
  3. Удалено ApartmentSearchRepository.java Файл.

Эти изменения дали мне необходимый ответ! :)

0 голосов
/ 30 октября 2018

Насколько я знаю, вы можете использовать @JsonProperty для сопоставления POJO с ответом на запрос, но вы теряете возможность использовать методы динамического поиска (findBy *) для данных пружин. Генерирование данных пружин в динамическом поиске зависит от отражения, и именно здесь имена полей в вашем POJO становятся важными.

Не могли бы вы изменить названия полей вашего POJO или в ваших документах, чтобы это проверить? Или просто определить пользовательский запрос? Существует также мощный Java-API, где вы можете определить более сложные запросы: https://docs.spring.io/spring-data/elasticsearch/docs/current/reference/html/#elasticsearch.misc.filter

...