We said that the search() method returned all the records matching the domain. This is not completely true. The method ensures that only records to which the user performing the search has access are returned. Additionally, if the model has a boolean field called active and no term of the search domain is specifying a condition on that field, then an implicit condition is added by search to only return active=True records. So, if you expect a search to return something but you only get empty recordsets, ensure that you check the value of the active field (if present) and to check for record rules.
Refer to the Calling a method with a different context recipe in Chapter 9, Advanced Server-Side Development Techniques, for a way to not have the implicit active = True condition added. Take a look at the Limit record access using record rules recipe in Chapter 11, Access Security, for more information about record-level access rules.
If for some reason, you find yourself writing raw SQL queries to find record IDs, ensure that you use self.env['record.model'].search([('id', 'in', tuple(ids))]).ids after retrieving the IDs to ensure that security rules are applied. This is especially important in multicompany Odoo instances where record rules are used to ensure proper discrimination between companies.