Couchbase:如何维护没有重复元素的数组?
Couchbase : How to maintain arrays without duplicate elements?
我们有一家 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]
我正在使用 子文档 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]
选项 2 "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.
有没有更好的方法来进行此更新?
需要purchased_product_ids订购吗?如果没有,您可以将其转换为地图,例如
{
"customer_id" : 1000
"purchased_product_ids" : {1: {}, 3: {}, 5: {}, 2: {}, 4: {}}
}
然后使用 subdoc 写入该地图,知道您不会发生冲突(假设产品 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_ids要下单,可以写下订单的时间戳,比如1: {date: <TIMESTAMP>}
,然后在取货的时候在代码里下单。)
您可以使用 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
我们有一家 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]
我正在使用 子文档 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]
选项 2 "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.
有没有更好的方法来进行此更新?
需要purchased_product_ids订购吗?如果没有,您可以将其转换为地图,例如
{
"customer_id" : 1000
"purchased_product_ids" : {1: {}, 3: {}, 5: {}, 2: {}, 4: {}}
}
然后使用 subdoc 写入该地图,知道您不会发生冲突(假设产品 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_ids要下单,可以写下订单的时间戳,比如1: {date: <TIMESTAMP>}
,然后在取货的时候在代码里下单。)
您可以使用 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