Indexing/search 版本间的算法稳定性
Indexing/search algorithm stability between versions
我正在从 Elasticsearch 1.5
迁移到 7.10
需要进行多项更改,最相关的更改是版本 6 中删除了文档类型概念,为了处理它我介绍了一个新字段 doc_type
然后我在搜索时匹配它。
我的问题是,当我进行相同的(或等价的,因为有一些变化)搜索查询时,我应该期望得到完全相同的结果集吗?因为我有一些差异,所以我想弄清楚我是否在新映射或搜索查询中破坏了某些东西。
提前谢谢你
在第一个问题后编辑:
总的来说:我有一个与 ES 1.5
通信的服务,我必须将它迁移到 ES 7.10
保持外部 API 尽可能稳定。
- 我没有使用评分。
- 以前我有文档类型
A
和 B
,当我进行这样的查询时,例如:host/indexname/A,B/_search
,迁移后我保留 A
或 B
在 doc_type
中,查询变为 host/indexname/_search
,正文中带有 "bool":{"should":[{"terms":{"doc_type":["A"],"boost":1.0}},{"terms":{"doc_type":["B"],"boost":1.0}}],"adjust_pure_negative":true,"boost":1.0}
。如果我将它放在 A
和 B
的不同索引中,并且用户想要在这两个索引中匹配,我将不得不“合并”两个查询的搜索响应,我不知道哪个为此,我应该遵循策略,所以将它们放在一起,我会得到来自 ES 的混合 (doc_type
) 结果的响应。我遵循了这种特定方法 https://www.elastic.co/blog/removal-of-mapping-types-elasticsearch#custom-type-field
- 差异不是很大,很难展示一个具体的例子,因为它是一个复杂的 data/doc 结构,但想法是,对于
1.5
给出的查询有这样的响应,例如:
[a, b, c, d, e, f, g, h, i, j]
(其中每个都可以有任何类型 A
或 B
)
对于 7.10,我收到如下回复:
[a, b, e, c, d, f, g, h, i, j]
或 [a, b, c, d, e, g, i, j, k]
第二次编辑:
此查询已从 java 客户端生成。
{
"from":0,
"size":100,
"query":{
"bool":{
"must":[
{
"query_string":{
"query":"mark_deleted:false",
"fields":[
],
"type":"best_fields",
"default_operator":"or",
"max_determinized_states":10000,
"enable_position_increments":true,
"fuzziness":"AUTO",
"fuzzy_prefix_length":0,
"fuzzy_max_expansions":50,
"phrase_slop":0,
"escape":false,
"auto_generate_synonyms_phrase_query":true,
"fuzzy_transpositions":true,
"boost":1.0
}
},
{
"bool":{
"should":[
{
"terms":{
"type":[
"A"
],
"boost":1.0
}
},
{
"terms":{
"type":[
"B"
],
"boost":1.0
}
},
{
"terms":{
"type":[
"D"
],
"boost":1.0
}
}
],
"adjust_pure_negative":true,
"boost":1.0
}
}
],
"adjust_pure_negative":true,
"boost":1.0
}
},
"post_filter":{
"term":{
"mark_deleted":{
"value":false,
"boost":1.0
}
}
},
"sort":[
{
"a_specific_date":{
"order":"desc"
}
}
],
"highlight":{
"pre_tags":[
"<b>"
],
"post_tags":[
"</b>"
],
"no_match_size":120,
"fields":{
"body":{
"fragment_size":120,
"number_of_fragments":1
}
}
}
}
首先,由于您不关心得分,因此您应该在顶层使用 bool/filter
而不是 bool/must
,否则您的结果默认按 _score
排序,介于1.7 和 7.10,变化如此之多以至于它可以解释你得到的差异。因此,您最好使用 _score
以外的任何其他字段对结果进行简单排序
其次,您可以使用简单的 terms
查询来代替 type
上的 bool/should
,它的工作完全相同,但方式更简单:
{
"from": 0,
"size": 100,
"query": {
"bool": {
"filter": [
{
"query_string": {
"query": "mark_deleted:false",
"fields": [],
"type": "best_fields",
"default_operator": "or",
"max_determinized_states": 10000,
"enable_position_increments": true,
"fuzziness": "AUTO",
"fuzzy_prefix_length": 0,
"fuzzy_max_expansions": 50,
"phrase_slop": 0,
"escape": false,
"auto_generate_synonyms_phrase_query": true,
"fuzzy_transpositions": true,
"boost": 1
}
},
{
"terms": {
"type": [
"A",
"B",
"C"
]
}
}
]
}
},
"post_filter": {
"term": {
"mark_deleted": {
"value": false,
"boost": 1
}
}
},
"sort": [
{
"a_specific_date": {
"order": "desc"
}
}
],
"highlight": {
"pre_tags": [
"<b>"
],
"post_tags": [
"</b>"
],
"no_match_size": 120,
"fields": {
"body": {
"fragment_size": 120,
"number_of_fragments": 1
}
}
}
}
最后,我不确定您为什么要使用 query_string
查询来对 mark_deleted:false
进行精确匹配,这对我来说没有意义。一个简单的 term
查询在这里会更好也更合适。
也不清楚为什么你删除了所有在你的 post_filter
中也有 mark_deleted:false
的结果,因为它与你的 query_string
约束中的条件相同。
我正在从 Elasticsearch 1.5
迁移到 7.10
需要进行多项更改,最相关的更改是版本 6 中删除了文档类型概念,为了处理它我介绍了一个新字段 doc_type
然后我在搜索时匹配它。
我的问题是,当我进行相同的(或等价的,因为有一些变化)搜索查询时,我应该期望得到完全相同的结果集吗?因为我有一些差异,所以我想弄清楚我是否在新映射或搜索查询中破坏了某些东西。
提前谢谢你
在第一个问题后编辑:
总的来说:我有一个与 ES 1.5
通信的服务,我必须将它迁移到 ES 7.10
保持外部 API 尽可能稳定。
- 我没有使用评分。
- 以前我有文档类型
A
和B
,当我进行这样的查询时,例如:host/indexname/A,B/_search
,迁移后我保留A
或B
在doc_type
中,查询变为host/indexname/_search
,正文中带有"bool":{"should":[{"terms":{"doc_type":["A"],"boost":1.0}},{"terms":{"doc_type":["B"],"boost":1.0}}],"adjust_pure_negative":true,"boost":1.0}
。如果我将它放在A
和B
的不同索引中,并且用户想要在这两个索引中匹配,我将不得不“合并”两个查询的搜索响应,我不知道哪个为此,我应该遵循策略,所以将它们放在一起,我会得到来自 ES 的混合 (doc_type
) 结果的响应。我遵循了这种特定方法 https://www.elastic.co/blog/removal-of-mapping-types-elasticsearch#custom-type-field - 差异不是很大,很难展示一个具体的例子,因为它是一个复杂的 data/doc 结构,但想法是,对于
1.5
给出的查询有这样的响应,例如:[a, b, c, d, e, f, g, h, i, j]
(其中每个都可以有任何类型A
或B
) 对于 7.10,我收到如下回复:[a, b, e, c, d, f, g, h, i, j]
或[a, b, c, d, e, g, i, j, k]
第二次编辑: 此查询已从 java 客户端生成。
{
"from":0,
"size":100,
"query":{
"bool":{
"must":[
{
"query_string":{
"query":"mark_deleted:false",
"fields":[
],
"type":"best_fields",
"default_operator":"or",
"max_determinized_states":10000,
"enable_position_increments":true,
"fuzziness":"AUTO",
"fuzzy_prefix_length":0,
"fuzzy_max_expansions":50,
"phrase_slop":0,
"escape":false,
"auto_generate_synonyms_phrase_query":true,
"fuzzy_transpositions":true,
"boost":1.0
}
},
{
"bool":{
"should":[
{
"terms":{
"type":[
"A"
],
"boost":1.0
}
},
{
"terms":{
"type":[
"B"
],
"boost":1.0
}
},
{
"terms":{
"type":[
"D"
],
"boost":1.0
}
}
],
"adjust_pure_negative":true,
"boost":1.0
}
}
],
"adjust_pure_negative":true,
"boost":1.0
}
},
"post_filter":{
"term":{
"mark_deleted":{
"value":false,
"boost":1.0
}
}
},
"sort":[
{
"a_specific_date":{
"order":"desc"
}
}
],
"highlight":{
"pre_tags":[
"<b>"
],
"post_tags":[
"</b>"
],
"no_match_size":120,
"fields":{
"body":{
"fragment_size":120,
"number_of_fragments":1
}
}
}
}
首先,由于您不关心得分,因此您应该在顶层使用 bool/filter
而不是 bool/must
,否则您的结果默认按 _score
排序,介于1.7 和 7.10,变化如此之多以至于它可以解释你得到的差异。因此,您最好使用 _score
其次,您可以使用简单的 terms
查询来代替 type
上的 bool/should
,它的工作完全相同,但方式更简单:
{
"from": 0,
"size": 100,
"query": {
"bool": {
"filter": [
{
"query_string": {
"query": "mark_deleted:false",
"fields": [],
"type": "best_fields",
"default_operator": "or",
"max_determinized_states": 10000,
"enable_position_increments": true,
"fuzziness": "AUTO",
"fuzzy_prefix_length": 0,
"fuzzy_max_expansions": 50,
"phrase_slop": 0,
"escape": false,
"auto_generate_synonyms_phrase_query": true,
"fuzzy_transpositions": true,
"boost": 1
}
},
{
"terms": {
"type": [
"A",
"B",
"C"
]
}
}
]
}
},
"post_filter": {
"term": {
"mark_deleted": {
"value": false,
"boost": 1
}
}
},
"sort": [
{
"a_specific_date": {
"order": "desc"
}
}
],
"highlight": {
"pre_tags": [
"<b>"
],
"post_tags": [
"</b>"
],
"no_match_size": 120,
"fields": {
"body": {
"fragment_size": 120,
"number_of_fragments": 1
}
}
}
}
最后,我不确定您为什么要使用 query_string
查询来对 mark_deleted:false
进行精确匹配,这对我来说没有意义。一个简单的 term
查询在这里会更好也更合适。
也不清楚为什么你删除了所有在你的 post_filter
中也有 mark_deleted:false
的结果,因为它与你的 query_string
约束中的条件相同。