如何将Lucene查询字符串转换为Elasticsearch-Match_Prefix等等效字符串



我目前正在从SOLR v3迁移到Elasticsearch v5.11。我的问题是,如何将下面的查询字符串转换为Elasticsearch Match/Match Phrase等等效字符串。这可能吗?

(entityName:(john AND lewis OR "john lewis") 
OR entityNameText:(john AND lewis OR "john lewis")) 
AND (status( "A" OR "I" status))

我试着这样做,到目前为止只使用了第一组括号,但似乎不正确:

{
"bool": {
"should": [
[{
"bool": {
"should": [
[{
"match_phrase": {
"entityName": "john lewis"
}
}]
],
"must": [
[{
"match": {
"entityName": {
"query": "john lewis",
"operator": "and"
}
}
}]
]
}
}, {
"bool": {
"should": [
[{
"match_phrase": {
"entityNameText": "john lewis"
}
}]
],
"must": [
[{
"match": {
"entityNameText": {
"query": "john lewis",
"operator": "and"
}
}
}]
]
}
}]
]
}

}

感谢

更新:

entityName和entityNameText都映射为文本类型,具有用于搜索和查询的自定义分析器。状态被映射为关键字类型。

为未来感兴趣的人发布答案。不完全确定原因,但我使用ESQueryDSL编写了两个替代查询,发现它们与原始的Lucene查询等效,返回完全相同的结果。不确定这是赞成还是反对ESQueryDSL。

原始Lucene查询:

{
"query": {
"query_string" : {
"query" : "entityName:(john AND Lewis OR "john Lewis") OR entityNameText:(john AND Lewis OR "john Lewis")"
}
}

}

查询备选方案1:

{
"bool": {
"should": [
[{
"bool": {
"should": [
[{
"match": {
"entityName": {
"query": "john Lewis",
"operator": "and"
}
}
}, {
"match_phrase": {
"entityName": "john Lewis"
}
}]
]
}
}, {
"bool": {
"should": [
[{
"match": {
"entityNameText": {
"query": "john Lewis",
"operator": "and"
}
}
}, {
"match_phrase": {
"entityNameText": "john Lewis"
}
}]
]
}
}]
]
}
}

查询备选方案2

{
"bool": {
"should": [
[{
"multi_match": {
"query": "john Lewis",
"type": "most_fields",
"fields": ["entityName", "entityNameText"],
"operator": "and"
}
}, {
"multi_match": {
"query": "john Lewis",
"type": "phrase",
"fields": ["entityName", "entityNameText"]
}
}]
]
}
}

使用此映射:

{
"entity": {
"dynamic_templates": [{
"catch_all": {
"match_mapping_type": "*",
"mapping": {
"type": "text",
"store": true,
"analyzer": "phonetic_index",
"search_analyzer": "phonetic_query"
}
}
}],
"_all": {
"enabled": false
},
"properties": {
"entityName": {
"type": "text",
"store": true,
"analyzer": "indexed_index",
"search_analyzer": "indexed_query",
"fields": {
"entityNameLower": {
"type": "text",
"analyzer": "lowercase"
},
"entityNameText": {
"type": "text",
"store": true,
"analyzer": "text_index",
"search_analyzer": "text_query"
},
"entityNameNgram": {
"type": "text",
"analyzer": "ngram_index",
"search_analyzer": "ngram_query"
},
"entityNamePhonetic": {
"type": "text",
"analyzer": "ngram_index",
"search_analyzer": "ngram_query"
}
}
},
"status": {
"type": "keyword",
"norms": false,
"store": true
}
}
}
}

答案将取决于您如何指定映射,但我假设您进行了客户映射。

让我们先把不同的部分分解,然后再把它们重新组合起来。

状态("A"或"I"状态)

这是一个"terms"查询,可以将其视为SQL"IN"子句。

"terms": {
"status": [
"a",
"i"
]
}

实体名称:(john AND lewis或"john lewis")

ElasticSearch将字符串字段分解为不同的部分。我们可以通过使用另一个"术语"查询来利用这一点。我们不需要将其指定为3个不同的部分,ES将在后台处理。

"terms": {
"entityName": [
"john",
"lewis"
]
}

实体名称文本:(john AND lewis或"john lewis")

与上面完全相同的逻辑,只是在不同的字段上搜索

"条款":{"entityNameText":["约翰","lewis"]}

AND与OR

在ES查询中。And="必须"或="应该"。

把它们放在一起

GET test1/type1/_search
{
"query": {
"bool": {
"must": [
{
"terms": {
"status": [
"a",
"i"
]
}
},
{
"bool": {
"should": [
{
"terms": {
"entityName": [
"john",
"lewis"
]
}
},
{
"terms": {
"entityNameText": [
"john",
"lewis"
]
}
}
]
}
}
]
}
}
}

下面是我用来测试查询的完整设置的链接。

https://gist.github.com/jayhilden/cf251cd751ef8dce7a57df1d03396778

最新更新