Steve Fitzsimons
Steve Fitzsimons

Reputation: 3904

Spring data Elasticsearch nested search - jhipster

I am using the Jhipster project generator to create a basic CRUD application. The application has search functionality using org.spingframework.data.elasticsearch. I have a customer domain and an address domain as shown below.

/**
 * A Customer.
 */
@Entity
@Table(name = "CUSTOMER")
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
@Document(indexName="customer")
public class Customer implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @Column(name = "forename")
    private String forename;

    @Column(name = "surname")
    private String surname;

    @ManyToOne
    @Field(type = FieldType.Nested)
    private Address address;
}

/**
 * An Address.
 */
@Entity
@Table(name = "ADDRESS")
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
@Document(indexName="address")
public class Address implements Serializable {



 @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @Min(value = 1)
    @Max(value = 9999)        
    @Column(name = "number")
    private Long number;

    @NotNull
    @Size(min = 5, max = 50)        
    @Column(name = "line1", length = 50, nullable = false)
    private String line1;

    @Size(min = 5, max = 50)        
    @Column(name = "line2", length = 50)
    private String line2;

    @NotNull
    @Size(min = 2, max = 50)        
    @Column(name = "city", length = 50, nullable = false)
    private String city;

    @Size(min = 2, max = 50)        
    @Column(name = "county", length = 50)
    private String county;

    @Size(min = 2, max = 50)        
    @Column(name = "country", length = 50)
    private String country;

    @NotNull
    @Size(min = 7, max = 8)        
    @Column(name = "postcode", length = 8, nullable = false)
    private String postcode;

}

Each customer has an address. I have a many to one mapping on it so each address can have many customers.

Now in my resource I have the following search query.

/**
     * SEARCH  /_search/customers/:query -> search for the customer corresponding
     * to the query.
     */
    @RequestMapping(value = "/_search/customers/{query}",
        method = RequestMethod.GET,
        produces = MediaType.APPLICATION_JSON_VALUE)
    @Timed
    public List<Customer> searchCustomers(@PathVariable String query) {
        return StreamSupport
            .stream(customerSearchRepository.search(queryString(query)).spliterator(), false)
            .collect(Collectors.toList());
    }

Currently this will return a list of customers based on whatever criteria I enter much like using a search engine. However the search will not match against the address field in the customer domain. Ideally I would like to search for a certain customer surname at a certain postcode however currently it will only match against customer fields which are not address. If i modify the search query to use findByPostcode or something along those lines then I lose the ability to search by customer name/details.

To put it simply how can I search against customer details fields AND customer address fields without de-normalizing my database?

Upvotes: 2

Views: 743

Answers (1)

Jelil Adesina
Jelil Adesina

Reputation: 287

The document annotation on the address is not required, I mean:

`@ManyToOne
 @Field(type = FieldType.Nested)
 private Address address;`

should have been:

`@ManyToOne
 private Address address;`

Upvotes: 1

Related Questions