Frontend Form Search Users based on Tags Context:
I'm trying to build a search form that will filter users based on Name, Skills and School. Users who have any of the search criteria should appear in my results.

Name Is a fuzzy keyword search of user.fullName

Skills Is a multiple select of tags, where any should match (if multiple are selected)

Schools Is a single select of a tag.

Problem 1:
When I search just by tags, leaving the Name field blanks, only the last tag is used to return results. So if two users were tagged with multiple tags, only the one relating to the last search term tag will be returned.

Problem 2:
It seems I can't combine the query so that I am searching not only by 'who has these tags', but also 'who's name partially matches this search' as well.

Thanks for any suggestions!

Code: Form

&lt;form action="{{ url('search') }}"&gt;
    &lt;input type="search" name="qName" placeholder="Name" value="{{craft.app.request.getParam('qName')}}"&gt;

    &lt;label for="qSkills"&gt;Skills&lt;/label&gt;
    &lt;select multiple id="qSkills" name="qSkills[]"&gt;
        {% for item in craft.tags.group('profileSkills').all() %}
        &lt;option value="{{ item.title }}"&gt;{{item.title}}&lt;/option&gt;
        {% endfor %}
    &lt;/select&gt;

    &lt;label for="qSchool"&gt;School&lt;/label&gt;
    &lt;select id="qSchool" name="qSchool"&gt;
        &lt;option value=""&gt;All&lt;/option&gt;
        {% for item in craft.tags.group('schoolPrograms').all() %}
        &lt;option value="{{ item.id }}"&gt;{{item.title}}&lt;/option&gt;
        {% endfor %}
    &lt;/select&gt;

    &lt;input type="submit" value="Search"&gt;
&lt;/form&gt;


Code: Results (on same page)

&lt;div class="results"&gt;
    {% set searchName = craft.app.request.getParam('qName') %}
    {% set searchSkills = craft.app.request.getParam('qSkills') %}
    {% set searchSchool = craft.app.request.getParam('qSchool') %}
    {% set queryParams = {} %}

    {% if searchName is defined and searchName is not empty %}
        {% set queryParams = queryParams|merge({
            search: {
                query:'fullName:*' ~ searchName ~'*',
            },
        }) %}
    {% endif %}

    {% if searchSkills is defined and searchSkills is not empty %}
        {% set skillList = "" %}
        {% for skill in searchSkills %}
            {% set skillList = skillList ~ 'profileSkills:' ~  skill ~ " OR " %}
        {% endfor %}
        {% set queryParams = queryParams|merge({
            search: {
                query:  skillList,
            },
        }) %}

    {% endif %}

    {% if searchSchool is defined and searchSchool is not empty %}
        {% set queryParams = queryParams|merge({
            search: {
                query: 'profileSchoolProgram:' ~ searchSchool,
            },
        }) %}
    {% endif %}


    {% set entries = craft.users(queryParams).group('members')
        .orderBy('score')
        .all() 
    %}

    {% if entries|length %}
        &lt;p&gt;{{ entries|length }} results:&lt;/p&gt;
        &lt;ul&gt;
            {% for entry in entries %}
                &lt;li&gt;&lt;a href="{{ entry.url }}"&gt;{{ entry.fullName }}&lt;/a&gt;&lt;/li&gt;
            {% endfor %}
        &lt;/ul&gt;
    {% else %}
        &lt;p&gt;Your search didn’t return any results.&lt;/p&gt;
    {% endif %}
&lt;/div&gt;
In order to get at the tag relationships, I think you'll need to use the relatedTo parameter instead of search. You'll still use search for the full-name search. This should solve both your problems.

The tricky part is fetching the appropriate elements to pipe into relatedTo() - you can't just send through the raw title string from the post data - you'll need to fetch the actual element ids.

Here's a very rough example. You'll need to replace 'facetFieldHandle_n` with the field handle names of your tag selector fields held against the users.

{% set facet1 = craft.tags.title(searchSkills).ids() %}
{% set facet2 = craft.tags.title(searchSchool).ids() %}

{% set params = ['and',
    { targetElement: facet1, field: 'facetFieldHandle_1' },
    { targetElement: facet2, field: 'facetFieldHandle_2' }
] %}

{% set users = craft.users.relatedTo(params).search(searchName).orderBy('score').all() %}

&lt;ul&gt;
    {% for user in users %}
        &lt;li&gt;{{ user.fullName }}&lt;/li&gt;
    {% endfor %}
&lt;/ul&gt;