회사에서 elasticsearch 와 라라벨을 혼용해서 사용하고 있는데, laravel-scout 라는 패키지를 도입해서 사용하고 있다. 사용하기가 어렵긴하지만 없는 것보다 낫다고 생각하고 쓰고있는데, 최근에 nested type 를 검색단에 넣어야되어 너무 고민이 많았다. nested type만 넣으면 문제가 안되는데 nested + query_string + term 을 이렇게 다 섞어야되서 머리가 터지는줄...
1.searchBuilder를 사용하여 아래처럼 search를 하고 있었다.
Model::search($keyword)->where()~~;
2.nested 타입 자체의 쿼리도 너무 어려웠다. 아래처럼 사용이 되는데 여기에 추가를 해야하니 죽을 맛이였다.
[
"nested" => [
"path" => "field"
"query" => [
"bool" => [
"should" => [
"terms" => [
"field.sub_field" => $value
]
]
]
]
]
]
그래서 searchRule은 이미 지정이 되어있어서 이 타입을 쓸때만 rule를 다른 거로 지정해줬다.
Model::search($value)->rule(nested type query);
3.그런데, searchBuilder에서 $keyword가 만약에 특정값이 존재하지 않고 특정 필드만을 조회하게 되면 searchBuilder가 아닌 filterBuilder를 사용하게 된다. 이때 filterBuilder는 rule를 사용하지 못한다 ㅎ.... 그래서 머리를 쥐어짜매다가 생각한 방법은, $keyword에 값이 존재하지 않을때 일단 쿼리문을 받고! searchBuilder에서 rule를 두 개로 분기하는 방법을 생각해냈다. (ㅠㅠㅠ)
결론적으로는, $keyword 값이 없을때는 아래와 같은 형태의 search rule이,
$searchQuery = [
'must' => [
[
"nested" => [
"path" => "field",
"query" => [
"bool" => [
"should" => [
"terms" => [
"field.sub_field" => $value
]
]
]
]
]
]
]
];
$keyword 값이 있을때는 아래와 같은 search rule이 완성되었다.
$searchQuery = [
'must' => [
[
'query_string' => [
'query' => $query
]
]
]
];
$nestedQuery = [
"nested" => [
"path" => "field",
"query" => [
"bool" => [
"should" => [
"terms" => [
"field.property" => $value
]
]
]
]
]
];
array_push($searchQuery['must'], $benefitQuery);