带有 belongsTo 约束的 Grails 3 ElasticSearch 嵌套对象查询给出了错误的匹配
Grails 3 ElasticSearch nested objects query with belongsTo constraint giving wrong matches
我想使用 ElasticSearch 从我的域 class 进行搜索,但这是一个嵌套查询,我想要的匹配深度为三层。
只有我正在搜索的域 class 被设置为根,所有其他都被设置为组件而不是可搜索配置的根。
当我进行搜索时,它会给我匹配项,但计数错误,里面的匹配项完全错误。
我应该得到 4000 个匹配项,但我得到了 20000 个匹配项,我不知道为什么它没有按预期工作。
当我开始摆弄时,我改变了我的域 classes 之间的映射,然后它给了我正确的匹配,但问题是我不想在我的产品中做这种改变环境。
我举两个例子。第一个显示我的域 classes 当前的关系(那个不起作用),另一个显示更改,使搜索正常工作。
示例不正确
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
}
}
正确工作示例
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
}
}
如您所见,关系的唯一区别是在第一个示例中 class D 属于 class C 而在第二个示例中 class D 只是一个字段class C. 在数据库中 D 在 C 中的引用在两种情况下完全相同。
我创建的搜索闭包如下所示:
bool {
must {
nested {
path = "b"
query {
nested {
path = "b.c"
query {
path = "b.c.d"
query {
bool {
must {
match("b.c.d.id": "142342342342")
}
}
}
}
}
}
}
}
}
我真的必须更改域 classes 的关系才能使搜索工作,还是我只是做错了搜索?
通常是什么导致了这个问题?
编辑
"c" 内字段 "d" 的 ElasticSearch 映射在两种情况下完全相同:
"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
}
}
}
编辑 2
所以问题似乎不在于映射,而是在对至少三层嵌套对象进行搜索时,ElasticSearch 无法正确找到与 匹配。我让它与 match_phrase.
一起工作
非常重要的一课,当通过例如 id 进行搜索时,您的查询具有多层嵌套并且您想要完全匹配,那么应该使用 match_phrase!
我建议使用 match_phrase 而不是 匹配 。
match_phrase 如果为查询字段定义了分析器,查询将分析输入并找到符合以下条件的文档:
- 所有术语都必须出现在字段中
- 它们必须与输入值具有相同的顺序
我想使用 ElasticSearch 从我的域 class 进行搜索,但这是一个嵌套查询,我想要的匹配深度为三层。
只有我正在搜索的域 class 被设置为根,所有其他都被设置为组件而不是可搜索配置的根。
当我进行搜索时,它会给我匹配项,但计数错误,里面的匹配项完全错误。
我应该得到 4000 个匹配项,但我得到了 20000 个匹配项,我不知道为什么它没有按预期工作。
当我开始摆弄时,我改变了我的域 classes 之间的映射,然后它给了我正确的匹配,但问题是我不想在我的产品中做这种改变环境。
我举两个例子。第一个显示我的域 classes 当前的关系(那个不起作用),另一个显示更改,使搜索正常工作。
示例不正确
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
}
}
正确工作示例
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
}
}
如您所见,关系的唯一区别是在第一个示例中 class D 属于 class C 而在第二个示例中 class D 只是一个字段class C. 在数据库中 D 在 C 中的引用在两种情况下完全相同。
我创建的搜索闭包如下所示:
bool {
must {
nested {
path = "b"
query {
nested {
path = "b.c"
query {
path = "b.c.d"
query {
bool {
must {
match("b.c.d.id": "142342342342")
}
}
}
}
}
}
}
}
}
我真的必须更改域 classes 的关系才能使搜索工作,还是我只是做错了搜索?
通常是什么导致了这个问题?
编辑
"c" 内字段 "d" 的 ElasticSearch 映射在两种情况下完全相同:
"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
}
}
}
编辑 2
所以问题似乎不在于映射,而是在对至少三层嵌套对象进行搜索时,ElasticSearch 无法正确找到与 匹配。我让它与 match_phrase.
一起工作非常重要的一课,当通过例如 id 进行搜索时,您的查询具有多层嵌套并且您想要完全匹配,那么应该使用 match_phrase!
我建议使用 match_phrase 而不是 匹配 。 match_phrase 如果为查询字段定义了分析器,查询将分析输入并找到符合以下条件的文档:
- 所有术语都必须出现在字段中
- 它们必须与输入值具有相同的顺序