REST API search for an exact match

I can’t find a way to search for an exact match via API call when looking for a user with a certain email address.

Let’s assume I have three users in the database:
User #1 email address: userone+test1@test.com
User #2 email address: usertwo+test1@test.com
User #3 email address: test1@test.com

Now I want to change the email address of user #3 in the database.
Therefore I try to get the corresponding ID of user #3 via REST API call:

/api/v1/users/search?query=email:test1@test.com

The API request returns user #1, user #2 and user #3 in the JSON response.
So what I have to do now in my code is to check for the exact match of the email address “test1@test.com” in all users returned in the JSON response object.

It would be more convenient if the API request would only return the user with an exact match in its email address.

Does anybody know if there is a way to achieve this via an API call?

Hi Hubertus,

try /api/v1/users/search?query=login:test1@test.com

so “login” instead of “email”. That should only return 1 unique value.

Cheers,
Gijs

Hi escomsilio,

this did not do the trick. I tried your suggestion but both calls
/api/v1/users/search?query=login:test1@test.com
and
/api/v1/users/search?query=email:test1@test.com

can both return more than one result. They do not look for an exact macht an seem to use the elastic search.

Thank you for your reply!

Hmm, sorry, than I have no idea. Maybe @MrGeneration has a solution?

Edit: Whoopsie, I should have tested the other way around too. :see_no_evil:
Checking with devs.

invalid statement

It’s the way you querry.
You’re actually running a not explicit search query (the UI does the same actually).

So do overcome your issue, you’ll need email: "<value>". Should work for login too.

See the differences:

# /api/v1/search?query=email:"sample@example.com"
{
    

   [...]
    "result": [
        {
            "id": 17,
            "type": "User"
        }
    ]
}

and your approach

# /api/v1/search?query=email:sample@example.com
{
    

   [...]

    "result": [
        {
            "id": 19,
            "type": "User"
        },
        {
            "id": 18,
            "type": "User"
        },
        {
            "id": 17,
            "type": "User"
        }
    ]
}
1 Like

Now that was a ride.

Developers provided the following background info:

Es is saving only “index” data in the attribute value. E. g. for attachments, not the attachment is saved, only the indexed words.
In this case es can may split the value of “email” into two words to save. one and sample@example.com. It’s up to the analyzer which is used for this attribute.
In case you want to search for the not indexed/analyzed values, you need to search for attribute.keyword. Note: This will not use any search indexes.

So in our case the correct API call would be:
/api/v1/search?query=email.keyword:"sample@example.com"

I did verify this behavior and it works on my machine™.

2 Likes

Does that also apply for
/api/v1/users/search?limit=1&query=email.keyword:"sample@example.com"
?

I verified that it is working using postman but couldn’t find documentation on it.

Would it make sense to add the “exact match” use case here in the API docu?

We are using this call for the “Create user if it does not exist, otherwise return existing user” use case. So we really need to be sure it is an exact match.

you can use the guess: method.
Body{
customer_id = “guess:$mail”
}

that does exactly the same.

ohhhh really???
I had soooo many Problems and now i see i just have to put the value in ’ '.

OMG im so exited weather my requests in powershell are working now.
search?query=state.name:‘open’%20AND%20group.name:‘groupname’&limit=10&expand=true"

nooo its not working again.

Personally I’d feel this making more sense within the search documentation of the user docs. Preferably the advanced search: zammad-user-documentation/search.rst at master · zammad/zammad-user-documentation · GitHub

The reason for that is that finding things in Zammad does affect “normal users” as well and may be a use case. Also I hate duplicate information to be honest. I’ll rework the api documentation in the future™ and will reference the search references of the user docs. I believe that should help better than sending a non technical user into the api reference

Use the .keyword slug, it’s your friend!
group.name.keyword

2 Likes

thank you so much for your fast answer. I am really frustradet, cause im working at this automation such a long time and it definitly seems randomly if it works or not. At first everything works
We Detect our Server Errors and the Ticket will be created automaticly in Zammad.
But When i want to control if there is already a ticket open, i have to use this Request. And i dont even know whats wrong. Would be awesome if you can check the following.

            $gettickets = 'https://mydomain.de/api/v1/tickets/search?query=group.name.keyword:"smartmanaged"%20AND%20state.name.keyword:"open"&expand=true'
           
            $tJson = (Invoke-WebRequest -Uri $gettickets -Headers $headers -Method GET).Content
            $tJson
            $tobjects = ConvertFrom-Json -InputObject $tJson
            $tobjects

and it gives me this
group : smartmanaged
ticket_time_accounting : {}
state : closed
priority : 2 normal

I dont even know even with your keyword slug :frowning:

Please ensure that your searchindex is allright.
It sounds like you have outdated data in your elasticsearch index.

You may want to ensure the exact search does work via the UI - if it does it also has to via API.