From 6de586ca74d1566e2ec07887a84ed334b223d47b Mon Sep 17 00:00:00 2001 From: Yehuda Sadeh Date: Fri, 17 Mar 2017 16:16:39 -0700 Subject: [PATCH] rgw: handle nested fields in es queries Signed-off-by: Yehuda Sadeh --- src/rgw/rgw_rest_es.cc | 58 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 55 insertions(+), 3 deletions(-) diff --git a/src/rgw/rgw_rest_es.cc b/src/rgw/rgw_rest_es.cc index 1a889c749fbed..d8d51a05d35aa 100644 --- a/src/rgw/rgw_rest_es.cc +++ b/src/rgw/rgw_rest_es.cc @@ -2,6 +2,7 @@ #include #include #include +#include #include "common/ceph_json.h" #include "rgw_common.h" @@ -150,6 +151,12 @@ public: virtual bool init(ESQueryStack *s) = 0; virtual void dump(Formatter *f) const = 0; + + virtual bool leaf_field_name(string *name) { + return false; + } + + virtual void leaf_field_rename(const string& new_name) {} }; static bool alloc_node(ESQueryStack *s, ESQueryNode **pnode); @@ -180,12 +187,13 @@ public: void dump(Formatter *f) const { f->open_object_section("bool"); const char *section = (op == "and" ? "must" : "should"); - f->open_object_section(section); - first->dump(f); - second->dump(f); + f->open_array_section(section); + encode_json("entry", *first, f); + encode_json("entry", *second, f); f->close_section(); f->close_section(); } + }; class ESQueryNode_Op : public ESQueryNode { @@ -206,6 +214,14 @@ public: } virtual void dump(Formatter *f) const = 0; + bool leaf_field_name(string *name) override { + *name = field; + return true; + } + + void leaf_field_rename(const string& new_name) override { + field = new_name; + } }; class ESQueryNode_Op_Equal : public ESQueryNode_Op { @@ -233,6 +249,34 @@ public: } }; +class ESQueryNode_Op_Nested : public ESQueryNode_Op { + string name; + ESQueryNode *next; +public: + ESQueryNode_Op_Nested(const string& _name, ESQueryNode *_next) : name(_name), next(_next) {} + ~ESQueryNode_Op_Nested() { + delete next; + } + + virtual void dump(Formatter *f) const { + f->open_object_section("nested"); + encode_json("path", "meta.custom-string", f); + f->open_object_section("query"); + f->open_object_section("bool"); + f->open_array_section("must"); + f->open_object_section("entry"); + f->open_object_section("match"); + encode_json("meta.custom-string.name", name.c_str(), f); + f->close_section(); + f->close_section(); + encode_json("entry", *next, f); + f->close_section(); + f->close_section(); + f->close_section(); + f->close_section(); + } +}; + static bool is_bool_op(const string& str) { return (str == "or" || str == "and"); @@ -272,6 +316,14 @@ static bool alloc_node(ESQueryStack *s, ESQueryNode **pnode) delete node; return false; } + string field_name; + if (node->leaf_field_name(&field_name) && + boost::algorithm::starts_with(field_name, "meta.custom.")) { + node->leaf_field_rename("meta.custom-string.value"); + field_name = field_name.substr(sizeof("meta.custom.")-1); + node = new ESQueryNode_Op_Nested(field_name, node); + + } *pnode = node; return true; } -- 2.39.5