如何在elasticsearch中执行多级逻辑查询

How to perform a multi level logical query in elasticsearch

假设我们有这样的查询

(a or b or c) and (x or y or z) and (f or g or h) ...

我们如何使用 Elasticsearch 执行此类查询? 我尝试了 bool 查询,但我仍然对 must、should... 子句以及如何在这些子句中放置不同的条件以获得合乎逻辑的结果感到困惑

这是我的数据样本(课程类型):

[{
        "_index": "training-hub",
        "_type": "courses",
        "_id": "58ad8090604aff26df131971",
        "_score": 1,
        "_source": {
          "title": "Getting Started with Vue.js",
          "description": "In this course, you will learn the basics of Vue.js framework and how to create amazing web applications using this framework",
          "slug": "hzrthtrjhyjyt--by--Jemli-Fathi",
          "format": [
            "Intra-entreprise"
          ],
          "duration": 6,
          "language": "EN",
          "requirements": [
            "Basics of web development"
          ],
          "tags": [],
          "audience": [
            "Web developers"
          ],
          "price": 600,
          "cover": "http://res.cloudinary.com/dqihnnzaj/image/upload/v1487840598/training-hub/k1h0tzciyjflqvtlyr2l.png",
          "scheduleUrl": "http://res.cloudinary.com/dqihnnzaj/image/upload/v1487765627/training-hub/sozofm68nrwxhta3ga3u.png",
          "trainer": {
            "firstname": "Jemli",
            "lastname": "Fathi",
            "photo": "https://ucarecdn.com/5923a1bb-3e77-47d0-bd5b-7d07b0f559fe/16487460_1269388943138870_3235853817844339449_o.jpg"
          },
          "courseCategory": {
            "name": "Game Development"
          },
          "createdAt": "2017-02-22T12:14:08.186Z",
          "updatedAt": "2017-02-24T10:39:22.896Z"
        }
      },
      {
        "_index": "training-hub",
        "_type": "courses",
        "_id": "58ad81c0604aff26df131973",
        "_score": 1,
        "_source": {
          "title": "Create your first Laravel application today!",
          "description": "In this course, you're gonna learn how create fancy web applications using Laravel PHP Framework ...",
          "slug": "sdvrehtrthrth--by--Jemli-Fathi",
          "format": [
            "Intra-entreprise",
            "Inter-entreprise"
          ],
          "duration": 6,
          "language": "EN",
          "requirements": [
            "Basics of Web development",
            "Basics of PHP language"
          ],
          "tags": [],
          "audience": [
            "Web developers",
            "PHP developers"
          ],
          "price": 600,
          "cover": "http://res.cloudinary.com/dqihnnzaj/image/upload/v1487841464/training-hub/dpgqbchualnfc78n69gs.png",
          "scheduleUrl": "http://res.cloudinary.com/dqihnnzaj/image/upload/v1487765627/training-hub/sozofm68nrwxhta3ga3u.png",
          "trainer": {
            "firstname": "Jemli",
            "lastname": "Fathi",
            "photo": "https://ucarecdn.com/5923a1bb-3e77-47d0-bd5b-7d07b0f559fe/16487460_1269388943138870_3235853817844339449_o.jpg"
          },
          "courseCategory": {
            "name": "Web Development"
          },
          "createdAt": "2017-02-22T12:19:12.376Z",
          "updatedAt": "2017-02-23T09:39:23.414Z"
        }
      },
      {
        "_index": "training-hub",
        "_type": "courses",
        "_id": "58aead4faecfc31e4559d49b",
        "_score": 1,
        "_source": {
          "title": "Getting Started with Docker",
          "description": "After taking this course, you will be able to use Docker in real life projects and you can bootstrap your projects into different containers",
          "slug": "regrehgreh--by--Jemli-Fathi",
          "format": [
            "Intra-entreprise"
          ],
          "duration": 5,
          "language": "EN",
          "requirements": [
            "Basic Linux Shell skills",
            "Basic knowledge of Linux environment"
          ],
          "tags": [],
          "audience": [
            "Dev-Ops",
            "Web Developers"
          ],
          "price": 999,
          "cover": "http://res.cloudinary.com/dqihnnzaj/image/upload/v1487939101/training-hub/vkqupkiqerq0kgjgd0km.png",
          "scheduleUrl": "http://res.cloudinary.com/dqihnnzaj/image/upload/v1487842509/training-hub/r9y1qisyfelseeuzgtt3.png",
          "trainer": {
            "firstname": "Jemli",
            "lastname": "Fathi",
            "photo": "https://ucarecdn.com/5acb1b5f-b550-4560-b085-2d75384e5ec8/13567067_1064268623650904_3773193220506255422_n.jpg"
          },
          "courseCategory": {
            "name": "Web Development"
          },
          "createdAt": "2017-02-23T09:37:19.758Z",
          "updatedAt": "2017-02-24T12:31:32.078Z"
        }
      }]

我真正需要的是像这样过滤课程:

(category1 or category2 ...) and (format1 or format2...) and (language1 or language2)...

Elasticsearch Query String Query 可以满足您的需求。

查看从官方文档中提取的以下代码片段here

GET /_search
{
    "query": {
        "query_string": {
            "query": "(content:this OR name:this) AND (content:that OR name:that)"
        }
    }
}

希望对您有所帮助!

您可以使用 bool queries combined with the terms query 实现所需的行为

GET _search
{
    "query" : {
      "bool": {
        "must": [   //AND
          {
            "terms": {
              "category.name": [ // Category with value VALUE1 or VALUE2
                "VALUE1",
                "VALUE2"
              ]
            }
          },
          {
            "terms": {
              "format": [// format with value FORMAT1 or FORMAT2
                "FORMAT1",
                "FORMAT2"
              ]
            }
          },
          {
            "terms": {
              "language": [// language with value LANG1 or LANG2
                "LANG1",
                "LANG2"
              ]
            }
          }
        ]
      } 

    }
}

此外,请确保用于 term 匹配的字段是 not_analyzed。 请从这里开始阅读映射:http://www.elasticsearch.org/guide/reference/mapping/.