cancel
Showing results for 
Search instead for 
Did you mean: 

Extend People API to query custom properties

mitchb
Champ in-the-making
Champ in-the-making
I have extended the Person model with a custom aspect using Jeff Potts tutorial here:
http://ecmarchitect.com/archives/2012/02/27/1555
(and the updated code by Sujay Pillai for the 2.2 SDK here: https://github.com/sujaypillai/someco-people).

I am able to view and edit my custom properties within Share - works great.

However, I would now like to customize Share's People Finder to retrieve users based on these new fields. I have customized the form, and it works for any property that is native to cmSmiley Tongueerson but will not work when querying against my custom properties. I then realized that when I query /api/people manually, none of my custom aspect properties are retrieved.

I would like to extend the People API so I can use it to query on my custom properties. The file I need to customize is here:
remote-api/config/alfresco/templates/webscripts/org/alfresco/repository/person/person.lib.ftl

I cannot find this anywhere in the SDK 2.2 - how do I override it with a customization?

Thanks!
8 REPLIES 8

steven_okennedy
Star Contributor
Star Contributor
Hi

The person.lib.ftl file can be found within the alfresco-remote-api.jar file. 

To do a customisation here, you need to either provide an overridden version of this file in your repository amp SDK project.  You would put the overridden file in the src/main/amp/config/extension/templates/webscripts/org/alfresco/repository/person folder and make sure your file is called person.lib.ftl.  You may also have to override the person.get.json.ftl file as well to ensure that it imports your overridden lib file - sometimes relative path based imports can cause havoc with the override mechanisms…

Regards

Steven

Hi Steven,

Thanks for that clarification. I added my custom properties to the person.lib.ftl and am now able to expose all properties at alfresco/service/api/people.
However it turns out that is not the end of the story, and I am beginning to think that wasn't the issue at all with my broken search.

When I try to use the "filter" parameter on that API request (http://localhost:8080/alfresco/service/api/people?filter=firstName:administrator), I can retrieve people as long as the property is on the type cmSmiley Tongueerson, whether or not that property is presented in the JSON response. So fields like email, skype, telephone, etc all work.

However when I use one of my custom properties in the filter, I always retrieve 0 results.

I think I need to configure the getPeopleImplSearch method in
https://github.com/Alfresco/community-edition/blob/master/projects/repository/source/java/org/alfres...
to include my custom properties, but I'm not sure how to specify that. Shouldn't my aspect be available within TYPE_PERSON?

If you could let me know how to adjust this code to include my:aspect in the filter, that would be great.

(from line 720)
<blockcode>
       query.append("TYPE:\"").append(ContentModel.TYPE_PERSON).append("\" AND (");
       
        if (tokens.length == 1)
        {
            // single word with no field will go against _PERSON and expand

            // fts-alfresco property search i.e. location:"maidenhead"
            query.append(term.substring(0, propIndex + 1)).append('"');
            if (propIndex < 0)
            {
                query.append('*');
            }
            query.append(term.substring(propIndex + 1));
            if (propIndex > 0)
            {
                query.append('"');
            }
            else
            {
                query.append("*\"");
            }
        }
</blockcode>

Thanks for your help!
Mitch

a_kholodkov
Champ in-the-making
Champ in-the-making

As other solution you can override cm:contentmodel.

Within this overridden content model you can add your properties to cmSmiley Tongueerson type.

In this case you can filter people by these properties without overriding of People.java.

steven_okennedy
Star Contributor
Star Contributor
Hi Mitch,

Having a quick look, it appears that the're no specific issue with the code present already from sending through other properties to search on, - the filters in play won't rule out anything from your custom aspect and the code above takes the search tokens and appends them to query string that will be sent.

However, there are 2 things to be wary of.  In your example firstName:Administrator, firstName is given without a model prefix (cmSmiley Happy.  This works because cm: is treated as the default prefix if none is given as far as I know.  For your custom property you'll need to make sure you include your custom model's prefix in order for Solr to pick it up properly.  You may hit problems here as the FTS language is similar to Lucene in that it uses ":" as a separator between the search property and its value, so a term like mySmiley Tonguerop:value doesn't work too cleanly.

The other thing to check is that your custom properties are actually set up to be indexed, so make sure that you have indexing turned on in your model definition for each property of your custom aspect

If you can, adding a loggging statement that prints out the final query that's going to be sent to Solr will help you a lot as you'll be able to get a much better idea of how the code is treating your search term, and you verify what it needs to be directly against Solr to get the results back.

Regards

Steven

Thanks for taking a look…I thought that might have had something to do with it. This is more of a question of how to include custom properties of a non-cm namespace prefix in a simple property:value syntax for FTS. I can't find any documentation anywhere for configuring this but I'll keep digging.

In fiddling around, I think I broke my sdk instance. I was trying to figure out where the Solr home was located in the repo SDK, couldn't, checked the admin settings for the search service, switched to Solr 4, (originally it was set to Solr 1, still don't get why), and now I can't retrieve anything, even with the same queries that worked before.

Any insight on how to bring my search service back? I'm kind of ready to retire this issue and wait for help from one of our developers.

Best regards,
Mitch

steven_okennedy
Star Contributor
Star Contributor
What I'd suggest, if you're up for it would be a slight alteration in that method you pointed out above, to allow for handling prefixes.  So normally in urls where alfresco has to deal with prefixes, it uses underscores instead.  That's what I would do here, so on your url you'd have ?filter=my_prop:value, and you'd just change the method slightly to replace with escaped colons ( \: ) before including the term in the query.  Below is an (untested) example of what I mean in the section that handles a single query term.  It's only done when propIndex > 0 as this is the scenario where a <prop>:<value> has been given instead of just <value>


if (tokens.length == 1)
{
  // single word with no field will go against _PERSON and expand

  //Substitute out an underscore for an escaped :, if propIndex > 0
  if(propIndex > 0)
  {
    term = term.replaceAll("_", "\\:");
  }

  // fts-alfresco property search i.e. location:"maidenhead"
  query.append(term.substring(0, propIndex + 1)).append('"');
  if (propIndex < 0)
  {
    query.append('*');
  }
  query.append(term.substring(propIndex + 1));
  if (propIndex > 0)
  {
    query.append('"');
  }
  else
  {
    query.append("*\"");
  }
}


My recommendation would be that you subclass this service with your own custom one, override the particular method above and override the spring bean that points it, pointing to your class instead.   This is far cleaner and more maintainable than trying to replace the class or do any other such messing around.

About your SDK Solr instance, it depends on how your running it.  If you're using something like the amp-to-war profile on a repository amp then there will be alfresco-dev-data folder that holds the content store, the H2 database files and the Solr indices.  You can remove the whole thing if you want to scratch your environment

Regards

Steven

I got everything back working, tried your suggestion and it works perfectly. I can now search within all properties using ?filter=my_property:value. And in the process I learned quite a lot about FTS, and overriding built-in Java services, so thank you for that.

I'll work on adjusting the people-finder.js onSearchClick method to factor this in to the query and we should be good to go!

Best regards,
Mitch

ddraper
World-Class Innovator
World-Class Innovator

FYI... Although not directly related to the back-end issues you're dealing with here, you might want to take a look at this blog post on using an Aikau version of the people-finder as it will give you more flexibility when you get around to customizing the Share UI (obviously it depends on how much front-end customization you require).

Getting started

Tags


Find what you came for

We want to make your experience in Hyland Connect as valuable as possible, so we put together some helpful links.