Searching for and extending User data

Hello,

I’m testing delivery tier queries in my back-end Java code, and I’m trying to understand why one query works for me but another doesn’t. I have a guess for this, but I’m hoping that someone might confirm it for me.

Here’s what works and returns results:

HstQueryBuilder.create(
    JcrUtils.getNodeIfExists("/content/documents", session))
        .ofTypes("myproject:contentdocument")
        .build(queryManager).execute().getHippoBeans(); // It works!

Please don’t mind the fact that I’m using JcrUtils - I’m working outside of the HstRequestContext, following the search bootstrapping advice presented under: https://documentation.bloomreach.com/library/concepts/fluent-search/fluent-hstquerybuilder-bootstrapping.html

At any rate, the above query works and returns the expected search results from the tree rooted under “/content/documents”. That’s great.

However, I wanted to experiment with searching for users, due to a feature I’m working on. Users are not defined under “/content/**” naturally. They’re under “/hippo:configuration/hippo:users” and their node primary types are “hipposys:user” as can be clearly seen by browsing existing users in cms/console.

I came up therefore with the following query, but no objects get returned:

HstQueryBuilder.create(
    JcrUtils.getNodeIfExists("/hippo:configuration/hippo:users", session))
        .ofTypes("hipposys:user")
        .build(queryManager).execute().getHippoBeans();  // No results...

I believe the reason why the former returns objects is because, in my project code, I have a ContentDocument.java bean there with the “public class …” line annotated as follows:

@Node(jcrType = "myproject:contentdocument")

My guess:

There is no corresponding ‘@Node(jcrType = “hipposys:user”)’ annotation anywhere in the platform for Users. Hence, they are not searchable, even though they exist in the repository.

Questions:

  1. Is my guess above correct?

  2. If it’s correct, is there a way for someone to define a JCR node-annoted class for JCR repository objects like Users so that they can be searched?

  3. Admittedly, I’m doing the above because I want to eventually link Bloomreach User accounts with additional information: eg., find a way to add additional fields to the User type (eg. say, “erpId”), link each user to a new Address type so that users may have addresses, etc. As you might imagine, some of this will matter for eCommerce, CRM, or related needs.

However, my thinking in (3), above, may not be ideal in Bloomreach: Maybe User objects in BR were designed to be relatively static in type/properties and, if I really need to add more information related to users, I should define a new Document type for users (eg. UserDocument). And perhaps assume a one-to-one association via User.username == UserDocument.username.

If anyone might be willing to share their opinions/design approaches to extending User data and searching for it, it would be very much appreciated!

As always, many thanks to the fine Bloomreach community!

-Nick

Yes. If the session doesn’t have access to the security user nodes, that’s another problem. But basically nodes, which are not documents or compounds under /content/..., are not designed to be mapped as HST Content Beans with @Node annotations. So, you can’t use HstQuery and HstQueryBuilder for those nodes.

Not in our frameworks. You need to rely on the low level JCR API instead in that case. ref) https://documentation.bloomreach.com/library/concepts/content-repository/jcr-interface.html

Could you elaborate the use case scenario further? For example, how do you want the user data updated by whom (admin user?) or by system automated triggering? When delivering pages with content, how do you want to use the associated user properties such as erpId? Do you need to pass that property to the backend for instance?

Regards,

Woonsan

1 Like

In addition to @woonsanko’s answer, check also following page:

Hello, Woonsan.

Firstly, thank you so much for your very clear response. I’ll be sure to inform my team members with your advice so that everyone is educated about this.

Secondly, I very much appreciate the reference to the JCR API. It’s nice to know that it’s available, should we ever need to use it.

Given your response, I’m inclined to believe that the best way forward is to create a new UserDocument type that we can search for by an identifier field. And that type should have some convenient 1-to-1 mapping with a Bloomreach User instance. However, we otherwise probably should not try to tamper with the Bloomreach ootb (non-document) User type.

You asked for further context concerning adding new fields to a user. I’ll elaborate here:

The idea behind an “erpId” field would be, as you guessed, for system automated triggering - or back-end processing. In other words, the end users themselves might never see this string value. In the future, we may need to add other related fields for integration with other systems that are also “user aware.” So I imagine this will come up from time to time.

Another requirement, as mentioned earlier, is the need to store addresses for Users. (And possibly other things.) I believe the way to move forward with that is to define something like an AddressDocument (in addition to UserDocument), and subsequently introduce a reference/link between them.

If you feel this approach sounds incorrect, I would be very grateful for any advice you may offer - as I want to be sure the team is following best practices to implementing such features in Bloomreach.

My experience comes from other platforms where we often times need to store some data related to site users, and that’s what I’m trying to describe above in terms of how this might be implemented in Bloomreach. Again, if you think I’m taking the wrong approach, please let me know.

Once again, Woonsan, I thank you very, very kindly for your prompt help and excellent advice! You rock, sir.

-Nick

Hi Nick,

Thanks for the details!

If you create or update the user nodes programmatically, you can use hipposys:externaluser node type [1] which extends the default hipposys:user node type, in order to allow to store any additional properties (e.g, for erpId or whatever) and use a property to make an association with UserDocument for example.

Considering that the cms user creation/update UI is not so extensible and that you need to have addresses for the user anyway, your approach makes sense to me.

Regards,

Woonsan

[1] https://documentation.bloomreach.com/library/concepts/security/repository-authorization-and-permissions.html

1 Like

Hello, @woonsanko.

We cannot thank you enough for your excellent recommendations. You have the gratitude of the entire team.

Many, many thanks - and an excellent weekend to you!
Nick

Hi @nick,

Thanks for the kind words and elaborations. That helps community a lot.

Cheers,

Woonsan

1 Like