ElasticSearch嵌套查询过滤器和动态数据

时间:2013-11-26 12:59:58

标签: elasticsearch pyelasticsearch

我使用以下pyelasticsearch代码创建索引:

编辑:再次更新11/12/13 18:31 GMT

    entry_mapping = {
        'product': {
            'properties': {
                '_advertiser_id': {'type': 'integer'},
                'advertiser': {'type': 'string'},
                'category': {'type': 'string'},
                'created_at': {'type': 'date'},
                'description': {'type': 'string'},
                'fields': {
                    'type': 'nested',
                    'properties': {
                        'gender': {'type': 'string'},
                        'short_type': {'type': 'string'}
                    }
                },
                'id': {'type': 'string'},
                'name': {'type': 'string'},
                'price': {'type': 'float'},
                'product_type': {'type': 'string'},
                'updated_at': {'type': 'date'},
                'variations': {'type': 'nested'},
            }
        }
    }

    es.create_index('product', settings={'mappings': entry_mapping})

导入数据后使用curl -XGET localhost:9200/products/_mapping返回的查询映射:

{
  "product" : {
    "product" : {
      "properties" : {
        "_advertiser_id" : {
          "type" : "integer"
        },
        "advertiser" : {
          "type" : "string"
        },
        "category" : {
          "type" : "string"
        },
        "created_at" : {
          "type" : "date",
          "format" : "dateOptionalTime"
        },
        "description" : {
          "type" : "string"
        },
        "fields" : {
          "type" : "nested",
          "properties" : {
            "gender" : {
              "type" : "string"
            },
            "short_type" : {
              "type" : "string"
            }
          }
        },
        "id" : {
          "type" : "string"
        },
        "images" : {
          "properties" : {
            "id" : {
              "type" : "string"
            },
            "url" : {
              "type" : "string"
            }
          }
        },
        "name" : {
          "type" : "string"
        },
        "price" : {
          "type" : "float"
        },
        "product_type" : {
          "type" : "string"
        },
        "updated_at" : {
          "type" : "date",
          "format" : "dateOptionalTime"
        },
        "variations" : {
          "type" : "nested",
          "properties" : {
            "colour" : {
              "type" : "string"
            },
            "female_tops" : {
              "type" : "string"
            },
            "image" : {
              "type" : "string"
            },
            "length" : {
              "type" : "string"
            },
            "size" : {
              "type" : "string"
            },
            "sleeve_length" : {
              "type" : "string"
            },
            "type" : {
              "type" : "string"
            },
            "zip_type" : {
              "type" : "string"
            }
          }
        }
      }
    }
  }
}

我使用以下查询成功查询:

curl -XGET 'http://127.0.0.1:9200/products/_search?size=100' -d '{"query": {"filtered": {"query": {"query_string": {"query": "t-shirt"}}}}}'

以下是一个示例结果:

{
   "_index":"product",
   "_type":"product",
   "_id":"525adf3fd1f4677e32d0f996",
   "_score":0.034907393,
   "_source":{
      "category":"T-Shirts",
      "advertiser":"string",
      "product_type":"Clothing",
      "description":"string",
      "fields":{
         "gender":"M"
      },
      "created_at":"2013-10-07T13:24:03.182000",
      "variations":[
         {
            "colour":"Grey",
            "sleeve_length":"Short sleeved",
            "size":"S"
         },
         {
            "colour":"Grey",
            "sleeve_length":"Short sleeved",
            "size":"M"
         },
         {
            "colour":"Grey",
            "sleeve_length":"Short sleeved",
            "size":"L"
         }
      ],
      "updated_at":"2013-10-19T13:54:29.796000",
      "price":12.0,
      "images":[
         {
            "url":"https://s3-eu-west-1.amazonaws.com/...",
            "id":"525adf23d1f4677e32d0f994",
            "resource_uri":""
         },
         {
            "url":"https://s3-eu-west-1.amazonaws.com/...",
            "id":"525adf30d1f4677e32d0f995",
            "resource_uri":""
         }
      ],
      "_advertiser_id":4,
      "id":"525adf3fd1f4677e32d0f996",
      "name":"Fresh Charcoal"
   }
}

我正在尝试使用pyelsticsearch执行以下查询。

    self.query = {
        'query': {
            'filtered': {
                'query': {
                    'query_string': {'query': self.query_str}
                },
                'filter': {
                    'and': [
                        {
                            'range': {
                                'price': {
                                    'gte': self.min_price,
                                    'lte': self.max_price
                                }
                            },
                        },
                        {
                            'terms': {
                                '_advertiser_id': self.advertisers,
                            },
                        },
                        {
                            'term': {
                                'fields.gender': self.gender.lower(),
                            },
                        },
                        {
                            'nested': {
                                'path': 'variations',
                                'query': {'match_all': {}},
                                'filter': {
                                    'and': [
                                        {
                                            'terms': {
                                                'variations.size': [s.lower() for s in self.sizes]
                                            },
                                        },
                                        {
                                            'term': {
                                                'variations.colour': self.colour.lower(),
                                            }
                                        }
                                    ]
                                }
                            }
                        },
                    ]
                },
            }
        }
    }

不幸的是,当存在与查询匹配的数据时,它无法返回任何结果。任何帮助将不胜感激。

更新时间:12/12/13 11:40 GMT

以下是上述查询代码生成的JSON示例。

curl -XGET 'http://127.0.0.1:9200/product/_search?size=100' -d '
{
   "query":{
      "filtered":{
         "filter":{
            "and":[
               {
                  "range":{}
               },
               {
                  "terms":{
                     "_advertiser_id":[
                        7,
                        4
                     ]
                  }
               },
               {
                  "term":{
                     "fields.gender":"m"
                  }
               },
               {
                  "nested":{
                     "filter":{
                        "and":[
                           {
                              "terms":{
                                 "variations.size":[
                                    "xs",
                                    "s",
                                    "m",
                                    "l",
                                    "xl",
                                    "xxl"
                                 ]
                              }
                           },
                           {
                              "term":{
                                 "variations.colour":"black"
                              }
                           }
                        ]
                     },
                     "path":"variations",
                     "query":{
                        "match_all":{

                        }
                     }
                  }
               }
            ]
         },
         "query":{
            "query_string":{
               "query":"t-shirt"
            }
         }
      }
   }
}'

UDPATED:12/12/13 11:51 GMT

事情变得陌生。在删除查询后,以下结果。

curl -XGET 'http://127.0.0.1:9200/product/_search?size=100' -d '{
   "query":{
      "filtered":{
         "filter":{
            "and":[
               {
                  "nested":{
                     "filter":{
                        "an":[
                           {
                              "terms":{
                                 "variations.size":[
                                    "xs",
                                    "s",
                                    "m",
                                    "l",
                                    "xl",
                                    "xxl"
                                 ]
                              }
                           },
                           {
                              "term":{
                                 "variations.colour":"black"
                              }
                           }
                        ]
                     },
                     "path":"variations",
                     "query":{
                        "match_all":{

                        }
                     }
                  }
               }
            ]
         },
         "query":{
            "query_string":{
               "query":"t-shirt"
            }
         }
      }
   }
}'

来自上述查询的示例结果数据:

{
   "_index":"product",
   "_type":"product",
   "_id":"525ade5ad1f4677e32d0f993",
   "_score":0.10493462,
   "_source":{
      "category":"T-Shirts",
      "advertiser":"...",
      "product_type":"Clothing",
      "description":"...",
      "fields":{
         "gender":"M"
      },
      "created_at":"2013-10-07T13:24:03.182000",
      "variations":[
         {
            "colour":"Black",
            "sleeve_length":"Short sleeved",
            "size":"S"
         },
         {
            "colour":"Black",
            "sleeve_length":"Short sleeved",
            "size":"M"
         },
         {
            "colour":"Black",
            "sleeve_length":"Short sleeved",
            "size":"L"
         }
      ],
      "updated_at":"2013-10-19T14:05:34.299000",
      "price":0.0,
      "images":[
         {
            "url":"...",
            "id":"525ade50d1f4677e30a2cb3a",
            "resource_uri":""
         }
      ],
      "_advertiser_id":4,
      "id":"525ade5ad1f4677e32d0f993",
      "name":"..."
   }
}

* 更新日期:21/12/2012 10:48 GMT *

我已经查出了有问题的查询部分 - 即。与整个查询结合使用时不返回任何结果。

{
    'term': {
        'fields.gender': self.gender.lower(),
    },
}

示范工作查询:

curl -XGET 'http://127.0.0.1:9200/product/_search?size=100' -d '{
   "query":{
      "filtered":{
         "filter":{
            "and":[
               {
                  "range":{
                     "price":{
                        "gte":0.0,
                        "lte":200.0
                     }
                  }
               },
               {
                  "terms":{
                     "_advertiser_id":[
                        7,
                        4
                     ]
                  }
               },
               {
                  "nested":{
                     "filter":{
                        "and":[
                           {
                              "terms":{
                                 "variations.size":[
                                    "xs",
                                    "s",
                                    "m",
                                    "l",
                                    "xl",
                                    "xxl"
                                 ]
                              }
                           },
                           {
                              "term":{
                                 "variations.colour":"black"
                              }
                           }
                        ]
                     },
                     "path":"variations",
                     "query":{
                        "match_all":{

                        }
                     }
                  }
               }
            ]
         },
         "query":{
            "query_string":{
               "query":"t-shirt"
            }
         }
      }
   }
}'

Exemplar unworking query:

curl -XGET 'http://127.0.0.1:9200/product/_search?size=100' -d '{
   "query":{
      "filtered":{
         "filter":{
            "and":[
               {
                  "range":{
                     "price":{
                        "gte":0.0,
                        "lte":200.0
                     }
                  }
               },
               {
                  "terms":{
                     "_advertiser_id":[
                        7,
                        4
                     ]
                  }
               },
               {
                  "term":{
                     "fields.gender":"m"
                  }
               },
               {
                  "nested":{
                     "filter":{
                        "and":[
                           {
                              "terms":{
                                 "variations.size":[
                                    "xs",
                                    "s",
                                    "m",
                                    "l",
                                    "xl",
                                    "xxl"
                                 ]
                              }
                           },
                           {
                              "term":{
                                 "variations.colour":"black"
                              }
                           }
                        ]
                     },
                     "path":"variations",
                     "query":{
                        "match_all":{

                        }
                     }
                  }
               }
            ]
         },
         "query":{
            "query_string":{
               "query":"t-shirt"
            }
         }
      }
   }
}'

2 个答案:

答案 0 :(得分:1)

您从elasticsearch返回的映射不会将您的“字段”和“变体”节点显示为嵌套。确保将映射之前的>映射到此类型中。删除索引,使用正确的映射创建索引,然后仅索引对象。

修改

查看更新后的信息后,原始查询中的空范围过滤器可能会过滤掉所有结果吗?
另外 - 你的“字段”字段也应该是嵌套的,是不是真的?您的查询不会将其视为嵌套。

答案 1 :(得分:0)

我认为您需要将嵌套字段设置为nested类型,如下所示:

{
   "products":{
      "product":{
         "properties":{
            "_advertiser_id":{
               "type":"long"
            },
            "advertiser":{
               "type":"string"
            },
            "category":{
               "type":"string"
            },
            "created_at":{
               "type":"date",
               "format":"dateOptionalTime"
            },
            "description":{
               "type":"string"
            },
            "fields":{
               "type" : "nested",
               "properties":{
                  "gender":{
                     "type":"string"
                  },
                  "short_type":{
                     "type":"string"
                  }
               }
            },
            "id":{
               "type":"string"
            },
            "images":{
               "type" : "nested",
               "properties":{
                  "id":{
                     "type":"string"
                  },
                  "url":{
                     "type":"string"
                  }
               }
            },
            "name":{
               "type":"string"
            },
            "price":{
               "type":"double"
            },
            "product_type":{
               "type":"string"
            },
            "updated_at":{
               "type":"date",
               "format":"dateOptionalTime"
            },
            "variations":{
               "type" : "nested", 
               "properties":{
                  "colour":{
                     "type":"string"
                  },
                  "female_tops":{
                     "type":"string"
                  },
                  "image":{
                     "type":"string"
                  },
                  "length":{
                     "type":"string"
                  },
                  "size":{
                     "type":"string"
                  },
                  "sleeve_length":{
                     "type":"string"
                  },
                  "type":{
                     "type":"string"
                  },
                  "zip_type":{
                     "type":"string"
                  }
               }
            }
         }
      }
   }
}