Searching for users on custom fields


  • I've added a custom field to the users of the forum by using the "filter:user.custom_fields" hook in a custom plugin, which is an awesome feature.

    The only problem I'm finding is I want to be able to search for users using this field, but I can't figure out how to use 'users.js' to achieve this. Is this possible with the current code?

    My alternative is to create another connection to the MongoDb, which seems a bit dirty, but it's what I'll do in the mean time.

    Any help would be great!

  • Community Rep

    It looks like you can do this using User.search(), but it's a little hard for me to follow, my guess as to what your search object would be is:

    {
    sortBy: 'yourfield',
    pagination: false,
    filterBy: [
      {field: 'yourfield', type:'=', value:'thevalueyouwant'},
      {repeat for every value you want}
    ]
    }
    

    That should give you data.users, which is an array of userData objects the match your filters and are sorted by yourfield.


  • Thanks @yariplus.
    Hadn't seen this response until just now!
    🙂

  • Community Rep

    @snodejoke

    Hey, yeah. I've been meaning to reply as well. What I typed above was actually and older 0.6.0 way of searching, and it doesn't actually work the way you want anyway.

    From what I can see, there is no way to search for custom fields using users.js

    It seems the proper way of doing would be to add a sorted set value when you create the field. If the field is a number, something like db.sortedSetAdd('users:yourfield', yourfield, uid, callback) then lookup with db.getSortedSetRangeByScore('users:yourfield', 0, count, min, max, callback), that's how I do it in my plugins now.

    If it's not a number, you need to store it as db.sortedSetAdd('yourfield:sorted', yourfield + ':' + uid, callback) then lookup with db.getSortedSetRangeByLex('yourfield:sorted', min, max, 0, count, callback)

    Here's how I sorted a custom field on my forum without creating a sortedset if you're interested:

    // Get all uids
    db.getSortedSetRange('users:joindate', 0, -1, function (err, uids) {		
    	// Get their custom_field
    	User.getMultipleUserFields(uids, ['uid', custom_field], function (err, users) {
    		// Sort by custom_field
    		async.sortBy(users, function (user, next) {
    			return next(null, user.custom_field);
    		}, function (err, results) {
    			console.log(results);
    		});
    	});
    });
    

    If not all users have the field, you can use the 'filter:users.get' hook to filter user results to only users that have the field, like I had to do.

    Hooks.filterUsersGet = function (users, next) {
    	// If 'custom_field' isn't in the results, don't filter.
    	if (users && users[0] && users[0].custom_field !== void 0) {
    		// Filter it out if it's null.
    		async.filter(users, function (user, next) {
    			return next(user.custom_field !== null);
    		}, function (results) {
    			next(null, results);
    		});
    	}else{
    		next(null, users);
    	}
    };
    

    Result:

    [ { uid: '18', uuid: '069a79f444e94726a5befca90e38aaf5' },
      { uid: '4', uuid: '294ecf637f1242c6a95d9cf8cc6da3ef' },
      { uid: '3', uuid: '32a46cc646d64ffea4da962692858288' },
      { uid: '5', uuid: '621ad5087ed448dd92dbc83950a222d9' },
      { uid: '17', uuid: 'a85e5f36dc5e465d9c86c6ad88912e99' },
      { uid: '1', uuid: 'f19cb1605bc24838835a07757d60ce80' } ]
    

Suggested Topics

  • 12
  • 2
  • 2
  • 2
  • 1
| |