2

I have a project that is using ObjectBox to store data locally.

When I perform a query in SQL, I can use "%" to get all of the items because I am using the "Like" keyword to match patterns.

Does ObjectBox have an equivalent way to do this in a query?

Hackmodford
  • 3,901
  • 4
  • 35
  • 78

2 Answers2

2

Not sure about the specifics about your use case, often a LIKE is used to find a string anywhere in the text. This is supported by ObjectBox using contains:

List<Note> endNotes = noteBox.query().contains(Note_.text, "end").build().find();

If you need something more powerful, please watch this feature request. Meanwhile, try to use a combination of contains (better performance) and filter (allows any complexity).

PS.: Of course you can have combinations of multiple contains conditions, and/or in combination with startsWith and endsWith.

Markus Junginger
  • 6,950
  • 31
  • 52
  • Contains almost worked, except it's not quite as powerful as LIKE. LIKE will let you specify things such the number of characters using % or _. https://www.w3schools.com/sql/sql_like.asp – Hackmodford Aug 14 '18 at 18:40
  • How to add .contains() with .or(), from a loop of unknown list of strings? – CaptRisky May 12 '19 at 06:25
1

I'm still interested if there is an official way to do this, but this is what I have come up with in the meantime.

In my query, I use the filter method.

private Query<InventoryItem> query = mBox
        .query()
        .greater(InventoryItem_.id, 0) //this will return all results
        .filter(new QueryFilter<InventoryItem>()
        {
            @Override
            public boolean keep(@NonNull InventoryItem entity)
            {
                if (like(entity.getDescription(), mSearchString + "%"))
                {
                    return true;
                }
                return false;
            }
        })
        .order(InventoryItem_.description)
        .build();

And here is how I can perform the LIKE keyword via a regular expression.

    private static boolean like(final String str, final String expr)
{
    String safeString = (str == null) ? "" : str;
    String regex = quoteMeta(expr);
    regex = regex.replace("_", ".").replace("%", ".*?");
    Pattern p = Pattern.compile(regex,
                                Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
    return p.matcher(safeString).matches();
}

private static String quoteMeta(String s)
{
    if (s == null)
    {
        throw new IllegalArgumentException("String cannot be null");
    }

    int len = s.length();
    if (len == 0)
    {
        return "";
    }

    StringBuilder sb = new StringBuilder(len * 2);
    for (int i = 0; i < len; i++)
    {
        char c = s.charAt(i);
        if ("[](){}.*+?$^|#\\".indexOf(c) != -1)
        {
            sb.append("\\");
        }
        sb.append(c);
    }
    return sb.toString();
}

Credit to How to implement a SQL like 'LIKE' operator in java?

Hackmodford
  • 3,901
  • 4
  • 35
  • 78