弹性搜索多个 AND + OR 查询

时间:2021-03-23 20:15:56

标签: elasticsearch nest

我的文档架构如下。

推文

Id
Title
Body
Privacy -> Values can only be ["Me", "Anyone", "Team"]
UserId

现在我只想检索标题包含“鸡肉三明治”的所有推文,这些推文具有“任何人”或“团队”的隐私。但是,在同一个查询中,如果该推文的 UserId 为“1456”,我只希望返回隐私为“我”的推文。

{
    "query": {
        "bool": {
            "must": [
                {
                    "bool": {
                        "must": [
                            {
                                "match": {
                                    "title": {
                                        "query": "chicken_sandwhich"
                                    }
                                }
                            }
                        ]
                    }
                }
            ],
            "should": [
                {
                    "bool": {
                        "should": [
                            {
                                "term": {
                                    "privacy": {
                                        "value": "Anyone"
                                    }
                                }
                            },
                            {
                                "term": {
                                    "privacy": {
                                        "value": "Team"
                                    }
                                }
                            }
                        ]
                    }
                },
                {
                    "bool": {
                        "must": [
                            {
                                "term": {
                                    "privacy": {
                                        "value": "Me"
                                    }
                                }
                            },
                            {
                                "term": {
                                    "userId.keyword": {
                                        "value": "my_user_id"
                                    }
                                }
                            }
                        ]
                    }
                }
            ]
        }
    }
}

如何构造该查询?我一直在苦苦挣扎,只是需要关于我正在寻找的查询类型的帮助。

2 个答案:

答案 0 :(得分:0)

看起来您需要将两个 must 包裹在一个 should 查询中:

{
  "query": {
    "bool": {
      "should": [
        {
          "bool": {
            "must": [
              {
                "match": {
                  "Title": "chicken sandwich"
                }
              },
              {
                "terms": {
                  "Privacy.keyword": [
                    "Anyone",
                    "Team"
                  ]
                }
              }
            ]
          }
        },
        {
          "bool": {
            "must": [
              {
                "term": {
                  "Privacy.keyword": {
                    "value": "Me"
                  }
                }
              },
              {
                "term": {
                  "UserId": {
                    "value": 1456
                  }
                }
              }
            ]
          }
        }
      ]
    }
  }
}

答案 1 :(得分:0)

您可能还想考虑query_string。这将让您以简单的方式编写查询,例如:

Title:"chicken sandwich" AND (
  Privacy:(Anyone OR Team)
  OR (Privacy:Me AND UserId:1456)
)

或实际格式:

{
  "query": {
    "query_string": {
      "query": "Title:\"chicken sandwich\" AND (Privacy:(Anyone OR Team) OR (Privacy:Me AND UserId:1456))",
    }
  }
}

请参阅此处的文档:https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-query-string-query.html