SQL-подобный запрос в ELasticsearch с AND ИЛИ

Привет, я все еще играю с asticsearch(V6.1.3) и нашел это удивительным, но все еще изнурительным. Я могу легко выполнить поиск по одному запросу и код для моей настройки:

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"}}})

Теперь я хочу выполнить следующий SQL-запрос (предположим, имя моей таблицы SQL:my-type):

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

Это означает, что я должен искать с несколькими терминами в разных областях. Кто-нибудь может подсказать мне, как это сделать? Спасибо

2 ответа

Я использую 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"                       
                ]
            }
        ]
    }
}

}

{
  "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*"
                  }
                }
              }
            ]
          }
        }
      ]
    }
  }
}

Выше приведен один из способов сделать это (я использую ES 5.3.3). Это не даст результатов для предоставленного вами набора данных. Попробуйте поиграть с этим немного. Есть и другие способы достижения того же поведения, но этот самый простой

Другие вопросы по тегам