Edited: see important note at the end, which was added after I posted originally and then re-read the question.
The only thing I can think of is to build an indexed table using hashes. But, this will undoubtedly weaken your security since we are exchanging full encryption that (hopefully) does not leak any information about the contents for tables of hashes, which do leak information about the contents of a user's data (knowing the number of terms indexed for a given account gives an attack a toehold for frequency analysis among other things).
Note: I am making the following assumption: you have a different iv for each user.
Prior to a database row being encrypted, you can read the rows and tokenize them into a table that will index those items. You would then hash the tokens with a salt generated form the iv. So, now, for a given user, "secretfoo" is saved in the index as
When you search, you'll need to loop through all the ivs to generate all the salts, then perform a search for the token
c9a60f248c3a99e2b7004061d5c74e5f2240426f1f0f95eaf5843aa875e68542 to find the record that contains 'secretfoo'.
This would be a faster search, but there is a trade of with speed for security here. Because you have essentially saved yourself a dictionary of hashes for a given word, if the database were to be exfiltrated, it's possible (but unlikely) that the indexed information could be used to assemble the original data. At the very least, it can be used to assemble metadata about the data. That being said, it would be computationally difficult.
Lets' assume you have 100,000 users with approximately 100 rows per user for a total table size of 100,000,000 rows of data.
Decrypting all 100,000,000 million to perform a non-indexed search will take mountains of time.
Under the paradigm above, you only have to generate 100,000 hashes and search for each of those once in the index to find the records you want.Additionally, we can match whole strings (the hash) and not have to perform any substring searches.
This has the advantage of computing 100,000 hashes and performing 100,000 searches on a BTREE indexed table that gives us good results.
As Mike Ounsworth pointed out, you are still going to have to decide what's sensitive and what's not sensitve data in order to do a search; however, having all the tokens SHA256 hashed is orders of magnitude better than plaintext.
After making my post, I re-read your question, and realized you've saved the iv in the database, which would make the index vulnerable to exfiltration.
The only way to fix that is to store the iv in a separate database that is not exposed to the web, and which can only be accessed via an API. This is a common setup in PCI compliant applications.
When making a query, your web-facing application would have to ask the secure server for the iv from which it would generate the hash, and perform the search.
This is a more complicated implementation, but if the iv is in the database that is web-facing, and it's exfiltrated, then all they have to do is loop through the ivs to decrypt the entire index.