2013-11-26 70 views
1

我有一个索引使用以下pyelasticsearch代码创建的:ElasticSearch嵌套查询的过滤器和动态数据

编辑:修订AGAIN 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(), 
              } 
             } 
            ] 
           } 
          } 
         }, 
        ] 
       }, 
      } 
     } 
    } 

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

UPDATE:13年12月12日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:13年12月12日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(), 
    }, 
} 

的Exemplar工作查询:

​​

的Exemplar unworking查询:

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" 
      } 
     } 
     } 
    } 
}' 
+0

查询对我来说看起来是正确的。你是否已经安装了elasticsearch头插件或任何等价物来检查索引映射? 或者卷曲索引以查看映射是否正确: 'curl -XGET localhost:9200/indexname/_mapping' – MeiSign

+0

Thanks @MeiSign。价格问题是该指数的问题。由于完整查询仍然无效,因此我更新了包含索引信息和新异常的帖子。 再次感谢,安德鲁。 – Prydie

+0

我的不好,我删除了我的错误答案。确实,它似乎是你索引他们嵌套。目前我没有其他想法,也无法在这里进行调试。对不起 – MeiSign

回答

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" 
        } 
       } 
      } 
     } 
     } 
    } 
} 
+0

嵌套结构在其中具有不同的字段时如何工作(即某些产品具有short_type,而其他产品可能具有top_type)。 – Prydie

1

您从elasticsearch获得的映射不会显示嵌套的“字段”和“变体”节点。确保你在之前将映射编入此类型的索引。删除索引,使用正确的映射创建索引,然后索引对象。

编辑

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

+0

我很确定这是我正在做的。我正在删除索引,使用上面的代码创建索引,然后使用自定义的Django管理命令填充索引。 – Prydie

+0

同样,在您从问题中发布的Elasticsearch(您从curl -XGET localhost:9200/products/_mapping获得的映射)中找到的映射中,变体节点不*标记为嵌套。确保Elasticsearch中的映射确实具有嵌套的映射。 –

+0

索引创建代码将它设置为测试,但不是吗?即'变异':{'type':'嵌套'}' – Prydie