I want to search from my domain class with ElasticSearch, but it's a nested query and the match, that I want, is three levels deep.
Only the domain class that I'm searching from is set as root, all others are set as components and not root for searchable configuration.
When I do the search it gives me matches, but the count is wrong and there are totally wrong matches inside there.
I should get 4000 matches, but I get 20000 matches and I have no clue why it doesn't work as expected.
When I started fiddling around, I changed the mappings between my domain classes and it then gave me correct matches, but the thing is that I do not want to do this kind of changes in my prod environment.
I'm going to give two examples. The first one shows my domain classes' relations currently (the one that doesn't work) and the other one is with the change, that made the search work correctly.
Not correctly working example
class A {
String id
String name
B b
static searchable = {
b component: true
}
}
class B {
String id
String name
C c
static searchable = {
root false
c component: true
}
}
class C {
String id
String name
static belongsTo = [d: D]
static searchable = {
root false
d component: true
}
}
class D {
String id
String name
static searchable = {
root false
}
}
Correctly working example
class A {
String id
String name
B b
static searchable = {
b component: true
}
}
class B {
String id
String name
C c
static searchable = {
root false
c component: true
}
}
class C {
String id
String name
D d
static searchable = {
root false
d component: true
}
}
class D {
String id
String name
static searchable = {
root false
}
}
As you can see the only difference in relations is that in the first example class D belongs to class C and in the second example class D is just a field in class C. In the database D is referenced in C exactly the same in both cases.
The search closure that I created looks like:
bool {
must {
nested {
path = "b"
query {
nested {
path = "b.c"
query {
path = "b.c.d"
query {
bool {
must {
match("b.c.d.id": "142342342342")
}
}
}
}
}
}
}
}
}
Do I really have to change my relations for the domain classes to make the search work or am I just doing the search wrong?
What could cause the issue in general?
EDIT
ElasticSearch mapping for the field "d" inside "c", is exactly the same in both cases:
"c":{
"type":"nested",
"properties":{
"class":{
"type":"string"
},
"dateCreated":{
"type":"date",
"format":"strict_date_optional_time||epoch_millis",
"include_in_all":true
},
"d":{
"type":"nested",
"properties":{
"class":{
"type":"string"
},
"id":{
"type":"string"
},
"name":{
"type":"string",
"term_vector":"with_positions_offsets",
"include_in_all":true
}
}
}
EDIT 2
So it seems that the problem was not rooted in the mappings, but rather that when doing a search with at least three levels of nested objects, then ElasticSearch wasn't able to correctly find the matches with the word match. I got it working with match_phrase.
So important lesson, when searching through for example ids and you your query has multi level nesting and you want an exact match, then one should use match_phrase!
I suggest to use match_phrase over match. match_phrase query will analyze the input if analyzers are defined for the queried field and find documents matching the following criteria :