項目需要,又開始找虐!最近兩週,因爲項目上的需求,用到了elasticsearch,帶着“迎難而上,不懂就學”的精神,開始了又一輪的找虐之旅。
這兩週完成相關功能開發後,感覺整體上elasticsearch其實還是比較容易上手的,不過其中也遇到了一些問題:比如,sql中的or操作或者no操作、添加字段根據term或者match匹配無法得到預期結果、text和keyword、index等問題,現在我們先來說說or操作的實現。
在elasticssearch中,or操作可以用should,比如滿足a=1或b=2的實現如下:
{"query": {
"bool": {
"should": [
{"match": {
"a": "1"
},
{"match": {
"b": "2"
}}
]
}}}
那如果我們將上述條件改爲:滿足a=1或b=2,並且c=3,也許很多朋友會犯跟我一樣的錯誤,即在上述代碼中增加一個must:c=3,即:
{"query": {
"bool": {
"must": [
{"match": {
"c": "3"
}}
],
"should": [
{"match": {
"a": "1"
},
{"match": {
"b": "2"
}}
]
}}}
乍一看,沒什麼問題,即滿足must中的條件,並滿足should中的一個條件,然而,這樣一運行,得到的結果好像只有c=3,而少了a和b的過濾;怎麼回事呢?
其實shoule在與must或者filter同級時,默認是不需要滿足should中的任何條件的,此時我們可以加上minimum_should_match 參數,來達到我們的目的,即上述代碼改爲:
{"query": {
"bool": {
"must": [
{"match": {
"c": "3"
}}
],
"should": [
{"match": {
"a": "1"
},
{"match": {
"b": "2"
}}
],
"minimum_should_match":1
}}}
上述代碼表示,必須滿足must中的所有條件,並且至少滿足should中的一個條件,這樣,就得到了預期的結果。
當然,我們也可以使用另一種方式實現,即將should放入到must中的一個bool條件中,即用分層的方式讓should和must不同時出現,實現如下:
{"query": {
"bool": {
"must": [
{
"match": { "c": "3" },
"bool": {
"should": [
{
"match": { "a": "1" },
"match": { "b": "2" }
}
}
]
}}}
上述兩種方式都可以解決should與must或者filter共存的問題,具體如何選擇,視具體情況而定即可。
相關的java和c#實現後續提供
博客:IT老五 簡書:ThinkinLiu