Couchbase:如何维护没有重复元素的数组?

时间:2018-11-28 10:21:31

标签: couchbase couchbase-java-api

我们有一个Couchbase商店,其中包含客户数据。

  • 每个客户在此存储桶中只有一个文档。
  • 每日交易将导致对此客户数据进行更新。

样本文件。让我们关注 purchased_product_ids 数组。

{
  "customer_id" : 1000
  "purchased_product_ids" : [1, 2, 3, 4, 5 ] 
      # in reality this is a big array - hundreds of elements
  ... 
  ... many other elements ...
  ...
} 

Existing purchased_product_ids : 
    [1, 2, 3, 4, 5]

products purchased today : 
    [1, 2, 3, 6]  // 6 is a new entry, others existing already

Expected result after the update: 
    [1, 2, 3, 4, 5, 6]

我正在使用 Subdocument API 来避免服务器和客户端之间的大量数据传输。

选项1“ arrayAppend”:

customerBucket.mutateIn(customerKey)
    .arrayAppend("purchased_product_ids", JsonObject for [1,2,3,6] )
    .execute();

It results in duplicate elements. 
"purchased_product_ids" : [1, 2, 3, 4, 5, 1, 2, 3, 6]

Option2“ arrayAddUnique”:

customerBucket.mutateIn(customerKey)
    .arrayAddUnqiue("purchased_product_ids", 1 )
    .arrayAddUnqiue("purchased_product_ids", 2 )
    .arrayAddUnqiue("purchased_product_ids", 3 )
    .arrayAddUnqiue("purchased_product_ids", 6 )
    .execute();

It throws exception for most of the times, 
because those elements already existing.

是否有更好的方法来进行此更新?

2 个答案:

答案 0 :(得分:4)

您需要订购Purchased_product_ids吗?如果没有,您可以将其转换为地图,例如

{
  "customer_id" : 1000
  "purchased_product_ids" : {1: {}, 3: {}, 5: {}, 2: {}, 4: {}}
}

,然后知道您不会冲突(假设产品ID是唯一的),然后使用子文档写入该地图:

customerBucket.mutateIn(customerKey)
   .upsert("purchased_product_ids.1", JsonObject.create()) // already exists
   .upsert("purchased_product_ids.6", JsonObject.create()) // new product
   .execute();

这将导致:

{
  "customer_id" : 1000
  "purchased_product_ids" : {1: {}, 3: {}, 6: {}, 5: {}, 2: {}, 4: {}}
}

(我在这里使用JsonObject.create()作为占位符,以防您需要为每个已支付的客户订单关联其他信息,但是您也可以只写null。如果确实需要定购Purchased_product_id,可以编写订单的时间戳,例如1: {date: <TIMESTAMP>},然后在获取时在代码中订购。)

答案 1 :(得分:3)

您可以使用N1QL以及ARRAY_APPEND()和ARRAY_DISTINCT()函数。

UPDATE customer USE KEYS "foo" 
SET purchased_product_ids = ARRAY_DISTINCT(ARRAY_APPEND(purchased_product_ids, 9))

假定这将是一条准备好的语句,并且密钥本身和新值将作为参数提供。

此外,如果您想一次向数组添加多个元素,则ARRAY_CONCAT()将是一个更好的选择。更多内容:

https://docs.couchbase.com/server/6.0/n1ql/n1ql-language-reference/arrayfun.html