如何在弹性搜索数组字段

时间:2017-11-06 11:02:53

标签: python elasticsearch

我想在数组字段中推送对象数据类型,我有错误,我的事情是映射

我使用Python来处理ElastickSearch

为客户创建映射

def create_customer_index():
    ''' Start creating customers index manually '''

    mapping = {
        "mappings": {
            "customer": {
                "properties": {
                    "created": {
                        "type": "long"
                    },
                    "updated": {
                        "type": "long"
                    },
                    "shopping_cart": {
                        "type": "text",
                        "fields": {
                            "keyword": {
                                "type": "keyword",
                                "ignore_above": 256
                            }
                        }
                    },

                }
            }
        }
    }

    es.indices.create(index='customers', body=mapping)
#end

使用此方法,我添加用户选择的产品和数组内的数量

def add_item_in_shopping_cart(uid, product_id, quantity=1):
    ''' Add new item in customer shopping cart '''

    print('Start adding a new item in shopping cart')

    # print('UID => ', uid)
    print('Product id to add is: => ', product_id)

    # 1st check if the user has this product on favorites,
    # 2nd if the user doesn't have this remove it from the list

    customer_shoping_cart = get_customer_shopping_cart(uid)
    print('CUSTUMER SHOPING CART => ', customer_shoping_cart)

    x = False

    for item in customer_shoping_cart:
        if item == product_id:
            x = True
    if x:
        print('Item already exist in shopping_cart')
        return 'item_already_exist_in_shopping_cart', 500
    else:
        print('Item dont exist in shopping_cart, i gona added')
        timestamp = int(round(time.time() * 1000))

        schema = {
            "product_id": product_id,
            "quantity" : 10
        }
        doc = {
            "script" : {
                "inline":"ctx._source.shopping_cart.add(params.data)",
                "params":{
                    "data":{
                        "product_id": product_id,
                        "quantity" : quantity
                    }
                }
            }
        }

        try:
            es.update(index="customers", doc_type='customer', id=uid, body=doc)
            es.indices.refresh(index="customers")
            return jsonify({'message': 'item_added_in_shopping_cart'}), 200

        except Exception as e:
            print('ERROR => ', e)
            return 'we have error', 500
#end

我有这个错误

  

错误=> TransportError(400,' mapper_parsing_exception','无法解析[shopping_cart]')

1 个答案:

答案 0 :(得分:0)

从您发布的映射看起来,ElasticSearch需要这样的文档:

{
  "created": 1510094303,
  "updated": 1510094303,
  "shopping_cart": "I am in a shopping cart"
}

或者像这样:

{
  "created": 1510094303,
  "updated": 1510094303,
  "shopping_cart": [
    "I am in a shopping cart",
    "me too!"
  ]
}

你试图对待"shopping_cart"是一个对象数组,它不是(它是一个字符串数组)。 ElasticSearch不允许将不适合映射的对象放入索引中。

首先应该尝试将映射更改为以下内容:

mapping = {
    "mappings": {
        "customer": {
            "properties": {
                "created": {
                    "type": "long"
                },
                "updated": {
                    "type": "long"
                },
                "shopping_cart": {
                    "properties": {
                        "product_id": {
                            "type": "keyword"
                        },
                        "quantity": {
                            "type": "integer"
                        }
                    }
                },

            }
        }
    }
}

此外,还要考虑在客户端完全更改文档,即在脚本中,并将新版本文档放在索引中(替换前一个),因为在实现逻辑中可能更容易(例如,不需要ElasticSearch端脚本来更新文档。

希望有所帮助。