简体   繁体   中英

SQL like query in ELasticsearch with AND OR

Hi I am still playing around with elasticsearch(V6.1.3) and found it amazing but still struglling.I can do single term query search easily and code follows for my setup:

from elasticsearch import Elasticsearch
es = Elasticsearch()
if not es.indices.exists(index="my-index"):
    customset={
        "settings": {
            "analysis": {
                "analyzer": {
                    "ngram_analyzer": {
                        "tokenizer": "ngram_tokenizer",
                        "filter": [
                            "lowercase",
                            "asciifolding"
                        ]
                    }
                },
                "tokenizer": {
                    "ngram_tokenizer": {
                        "type": "ngram",
                        "min_gram": 3,
                        "max_gram": 100,
                        "token_chars": [
                            "letter",
                            "digit"
                        ]
                    }
                }
            }
        },
        "mappings": {
            "my-type": {
                "properties": {
                    "demodata": {
                        "type": "text",
                        "fields": {
                            "ngram": {
                                "type": "text",
                                "analyzer": "ngram_analyzer",
                                "search_analyzer": "standard"
                            }
                        }
                    },
                    "Field1": {
                        "type": "text",
                        "fields": {
                            "ngram": {
                                "type": "text",
                                "analyzer": "ngram_analyzer",
                                "search_analyzer": "standard"
                            }
                        }
                    }
                }
            }
        }
    }

    es.indices.create(index="my-index", body=customset, ignore=400)
    docs=[
    { "demodata": "hELLO" ,"field1":"Alex","field2":"Red"},
    { "demodata": "hi" ,"field1":"Tom","field2":"Blue"},
    { "demodata": "bye" ,"field1":"Jack","field2":"Green"},
    { "demodata": "HeLlo WoRld!","field1":"Robert","field2":"Yellow" },
    { "demodata": "xyz@abc.com","field1":"Dave","field2":"White" }
    ]
    for doc in docs:
    res = es.index(index="my-index", doc_type="my-type", body=doc)



es.indices.refresh(index="my-index")
res=helpers.scan(client=es,scroll='2m',index="my-index", doc_type="my-type",query={"query": {"match": {"demodata.ngram": "Hello"}}})

Now I want to do following SQL like query (suppose my SQL table name:my-type):

SELECT * FROM my-type WHERE (demodata LIKE '%ell%' OR demodata LIKE '%orld%') AND (field1 LIKE '%red%' OR demodata LIKE '%yellow%')

That means I have to search with multi terms in different fields. Can anyone suggest me how to do that? Thanks

{
  "query": {
    "bool": {
      "must": [
        {
          "bool": {
            "minimum_should_match": 1, 
            "should": [
              {
                "wildcard": {
                  "demodata": {
                    "value": "*ell*"
                  }
                }
              },
              {
                "wildcard": {
                  "demodata": {
                    "value": "*orld*"
                  }
                }
              }
            ]
          }
        },
        {
          "bool": {
            "minimum_should_match": 1, 
            "should": [
              {
                "wildcard": {
                  "demodata": {
                    "value": "*yellow*"
                  }
                }
              },
              {
                "wildcard": {
                  "field1": {
                    "value": "*red*"
                  }
                }
              }
            ]
          }
        }
      ]
    }
  }
}

The above is one way of doing it (I'm using ES 5.3.3). This will yield no results for your provided dataset. Try playing with it a little. There are other ways of accomplishing the same behaviour, but this one the most straightforward

I'm using ES 5.6.2

{
"query": {
    "bool": {
        "should": {             
            "multi_match": {
                "query": "orld ell",
                "fields": [
                    "demodata"                                         
                ]
            }
        },
        "should": [
            "multi_match": {
                "query": "red",
                "fields": [
                    "field1"                       
                ]
            },
            "multi_match": {
                "query": "yellow",
                "fields": [
                    "demodata"                       
                ]
            }
        ]
    }
}

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM