Elasticsearch。查询嵌套对象中的一对属性

时间:2015-10-20 17:45:42

标签: elasticsearch

我的部分映射是:

class TelefonBok:
    def __init__(self):
        self.teleDic = {}
        kommandonDic = {"add": self.add, "lookup": self.lookup,
                    "alias": self.alias, "save": self.save,
                    "load": self.load, "remove": self.remove, "quit": self.my_quit, "change": self.change}

        while True:
            x = raw_input("telebok> ") #prompt
            y = x.split()
            try:
                kommandonDic[y[0]](*y[1:])
            except KeyError: 
                print "Denna funktion finns inte"
            except TypeError:
                print "du skriver fel antal argument"
            except SystemExit:
                print "Bye Bye" 
                break


    def find(self, namn):
        hittade = 0
        nr = 0
        for number, names in self.teleDic.items():
            if namn in names:
                nr = number
                hittade += 1 
        if hittade == 0:
            return 0
        elif hittade == 1:
            return nr
        else:
            return -1


    def add(self, namn, nummer):
        print "Saving..."
        self.teleDic[nummer] = [namn]
        print "Save complete."

    def lookup(self, namn = None):
        if namn == None: 
            print "Ge ett namn!"
        else:
            hittade = 0 #Hittade är 0 från början
            for number, names in self.teleDic.items():
                if namn in names: 
                    print number
                    hittade = 1
                    print "Done..."
            if hittade != 1:
                print "Namnet finns inte"

    def alias(self, namn, newname):
        if newname:
            nr = self.find(namn)
            if nr > 0: #om nr är större än 0...
                self.teleDic[nr].append(newname) 
                print "alias inserted..."


    def change(self, namn, newnumber, oldnr = None):
        if namn:
            nr = self.find(namn)
            if nr > 0: #om nr är större en 0.
                self.teleDic[newnumber] = self.teleDic[nr]
                del self.teleDic[nr]
                print "name changed..."
            elif nr == 0: 
                print "Hittar inga med det nummer"
            else:
                if oldnr:
                    self.teleDic[newnumber] = self.teleDic[oldnr]
                    del self.teleDic[oldnr]
                else:
                    print "Flera personer har detta namn, ge nummer"

    def save(self, filename):
        f = open(filename, "w")
        for number, names in self.teleDic.items():
            line = number + ";" + ";".join(names) + "\n"
            f.write(line)
            print "Saved..."

    def load(self, filename):
        self.teleDic = {}
        f = open(filename, "r")
        for line in f:
            line = line.split(";")
            nummer = line[0]
            namn = line[1:]
            self.teleDic[nummer] = namn
            print "loading done..."


    def remove(self, namn, nr=None):
        nummer = self.find(namn)
        if nummer > 0:
            del self.teleDic[nummer]
            print "Remove done..."
        elif nummer == 0: 
            print "Namnet finns inte"
        elif nummer == -1: 
            if nr:
                del self.teleDic[nr]
            else:
                print "Flera personer har detta namn, ge nummer"

    def my_quit(self):
        print "Bye bye..." 
        raise SystemExit



t = TelefonBok()

我需要过滤那些具有attribute_id =' x'使用给定id的attribute_value等于' y'。所以我需要匹配一对字段。可能吗?或者我是否需要将映射更改为以下内容:

"individual_attributes" : {
    "type" : "nested",
        "properties" : {
            "template_id" : {"type" : "integer"},
            "attributes_set" : {
                "type" : "nested",
                "properties" : {
                    "attribute_id" : {"type" : "integer"},
                    "attribute_value" : {"type" : "string", "index" : "not_analyzed"}
                }
            }
        }
    }

示例数据:

"individual_attributes" : {
    "type" : "nested",
        "properties" : {
            "template_id" : {"type" : "integer"},
            "attributes_set" : {
                "type" : "nested",
                "properties" : {
                    "attribute_id" : {"type" : "integer",
                        "properties" : {
                            "attribute_value" : {"type" : "string", "index" : "not_analyzed"}
                        }
                    },

                }
            }
        }
    }

我需要:SELECT * WHERE属性(例如16)= value(neque)。另一个词我需要匹配一个数据集中的字段对:

                  "attributes_set": [
                 {
                    "attribute_id": 17,
                    "attribute_value": "dolorum"
                 },
                 {
                    "attribute_id": 15,
                    "attribute_value": "at"
                 },
                 {
                    "attribute_id": 18,
                    "attribute_value": "maxime"
                 },
                 {
                    "attribute_id": 14,
                    "attribute_value": "et"
                 },
                 {
                    "attribute_id": 11,
                    "attribute_value": "nemo"
                 },
                 {
                    "attribute_id": 12,
                    "attribute_value": "rem"
                 },
                 {
                    "attribute_id": 10,
                    "attribute_value": "eius"
                 },
                 {
                    "attribute_id": 19,
                    "attribute_value": "deleniti"
                 },
                 {
                    "attribute_id": 13,
                    "attribute_value": "modi"
                 },
                 {
                    "attribute_id": 16,
                    "attribute_value": "neque"
                 }
              ]

2 个答案:

答案 0 :(得分:2)

这是一个简化的例子。您的第一个映射应该适合您想要做的事情。我拿出了一个级别的嵌套来简化解释,但同样的原则适用于任意级别的嵌套(如果你不知道如何概括我的例子我可以用另一个例子编辑答案)。

我设置了这样一个简单的映射:

PUT /test_index
{
   "mappings": {
      "doc": {
         "properties": {
            "attributes_set": {
               "type": "nested",
               "properties": {
                  "attribute_id": {
                     "type": "integer"
                  },
                  "attribute_value": {
                     "type": "string",
                     "index": "not_analyzed"
                  }
               }
            }
         }
      }
   }
}

然后添加两个文档,每个文档包含两个嵌套文档:

POST /test_index/doc/_bulk
{"index":{"_id":1}}
{"attributes_set": [{"attribute_id": 18,"attribute_value": "dolorum"},{"attribute_id": 15,"attribute_value": "at"}]}
{"index":{"_id":2}}
{"attributes_set": [{"attribute_id": 18,"attribute_value": "maxime"},{"attribute_id": 14,"attribute_value": "et"}]}

现在我可以查询具有特定嵌套文档的文档,如下所示:

POST /test_index/_search
{
   "filter": {
      "nested": {
         "path": "attributes_set",
         "filter": {
            "bool": {
               "must": [
                  {
                     "term": {
                        "attributes_set.attribute_id": {
                           "value": 18
                        }
                     }
                  },
                  {
                     "term": {
                        "attributes_set.attribute_value": {
                           "value": "maxime"
                        }
                     }
                  }
               ]
            }
         }
      }
   }
}

返回:

{
   "took": 24,
   "timed_out": false,
   "_shards": {
      "total": 5,
      "successful": 5,
      "failed": 0
   },
   "hits": {
      "total": 1,
      "max_score": 1,
      "hits": [
         {
            "_index": "test_index",
            "_type": "doc",
            "_id": "2",
            "_score": 1,
            "_source": {
               "attributes_set": [
                  {
                     "attribute_id": 18,
                     "attribute_value": "maxime"
                  },
                  {
                     "attribute_id": 14,
                     "attribute_value": "et"
                  }
               ]
            }
         }
      ]
   }
}

这是我用来测试它的所有代码:

http://sense.qbox.io/gist/5e75461a4f0cf96e012cbf0f8262b22f3f8e5ec0

这有帮助吗?

答案 1 :(得分:1)

看起来你已经有了完美的映射,所以你需要做的就是构建一个涉及nested查询的正确查询。

请参阅Elasticsearch文档,了解如何查询嵌套对象。查看他们的Querying a Nested Object文档,我认为这些文档提供了您需要的所有详细信息以及类似于您的案例的相关注释示例。

编辑:

抱歉,我刚刚注意到您关于映射的问题 - 您的第一张映射是正确的。