2013-11-26 4 views
1

Я индекс создан с помощью следующого pyelasticsearch кода:ElasticSearch фильтров вложенных запросов и динамическая данные

EDIT: ОБНОВЛЕН СНОВА 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(), 
    }, 
} 

Exemplar работает запрос:

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:

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

Спасибо @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': 'nested'} ' – Prydie

Смежные вопросы