Custom XATTR creation

Hi,
we are planning to move some attribute to meta xattr, is there a way to create a xattr value when we try to upsert a document.

Currently, i am able to do like below, but is there a better way?

Collection coll=cluster.bucket(“”).defaultCollection();
coll.upsert(“”, JsonObject.fromJson(channelId));
JsonArray channelArray=JsonArray.fromJson(“”);
MutateInResult resp = coll.mutateIn(“”, Arrays.asList(MutateInSpec.upsert(“$Channels”,channelArray).xattr()));

Hi @nagarajan_subbaraj !

It is indeed possible to upsert both the document content and an XATTR at the same time.

For the document content, the server wants you to use MutateInSpec.replace with an empty path.

SIDEBAR: Why not MutateInSpec.upsert? Your guess is as good as mine!

Another thing to note is that when doing mutateIn on a document that might not exist, it’s necessary to specify StoreSemantics.UPSERT.

Here’s a code snippet that puts it all together:

public static MutationResult upsertWithXattr(
  Collection collection,
  String documentId,
  Object documentValue,
  String xattrPath,
  Object xattrValue
) {
  return collection.mutateIn(
    documentId,
    List.of(
      MutateInSpec.replace("", documentValue),
      MutateInSpec.upsert(xattrPath, xattrValue).xattr().createPath()
    ),
    MutateInOptions.mutateInOptions()
      .storeSemantics(StoreSemantics.UPSERT)
  );
}

Call it like this:

upsertWithXattr(
  collection,
  documentId,
  Map.of("foo", "bar"),
  "myAttrs.magicWord",
  "xyzzy"
);

Then if you want, you can use lookupIn to get both the document content and XATTR at the same time, like this:

LookupInResult result = collection.lookupIn(documentId, List.of(
  LookupInSpec.get(""),
  LookupInSpec.get("myAttrs").xattr()
));

System.out.println("Content: " + new String(result.contentAsBytes(0)));
System.out.println("XATTRs: " + new String(result.contentAsBytes(1)));

which prints:

Content: {"foo":"bar"}
XATTRs: {"magicWord":"xyzzy"}

Thanks,
David

1 Like

Also note that your custom XATTR path must not start with a dollar sign ($), otherwise the server will interpret it as a virtual attribute, and prevent you from modifying it.

It shouldn’t start with an underscore (_) either, because that’s how the server identifies system attributes that require special privileges to access.

Thank you. Let me try it out.