Несколько условий и() в предложении where для Android-клиента couchbase lite

#android #couchbase-lite

Вопрос:

В моем приложении для Android мы используем версию базы данных couchbase lite 2.8.6

Я выполняю три запроса к базе данных.

  • Один пункт в предложении where.
 QueryBuilder.select(
    SelectResult.property("id"),
    SelectResult.property("timestamp"),
    SelectResult.property("rating"))
.from(DataSource.database(database))
.where(Expression.property("type").equalTo(Expression.string(DOC_TYPE)))
 

В результате я вижу три элемента из базы данных, напечатанных на консоли. Как и ожидалось. Формат здесь и ниже такой id|timestamp|rating

 4e39f79c-9e11-4aba-9fb6-95d910f46cd9|0|-2147483648
e95646ee-ba3a-4978-b2a8-5383f31be2f1|0|-2147483648
e02d0eb3-6c9b-4942-b43c-a752eefc77a8|1630525956184|2147483647
 
  • Я добавляю and() условие where() , чтобы получить все предметы, где type = 'type' AND rating < 1
 QueryBuilder.select(
    SelectResult.property("id"),
    SelectResult.property("timestamp"),
    SelectResult.property("rating"))
.from(DataSource.database(database))
.where(Expression.property("type").equalTo(Expression.string(DOC_TYPE))
   .and(Expression.property("rating").lessThan(Expression.intValue(1))
)
 

Результат такой , как и ожидалось, поскольку мы ищем все rating < 1 , третий элемент отфильтрован.

 4e39f79c-9e11-4aba-9fb6-95d910f46cd9|0|-2147483648
e95646ee-ba3a-4978-b2a8-5383f31be2f1|0|-2147483648
 
  • Наконец, я хочу увидеть записи, в которых type = 'type' AND rating < 1 AND timestamp <= 1
 QueryBuilder.select(
    SelectResult.property("id"),
    SelectResult.property("timestamp"),
    SelectResult.property("rating"))
.from(DataSource.database(database))
.where(Expression.property("type").equalTo(Expression.string(DOC_TYPE))
   .and(Expression.property("rating").lessThan(Expression.intValue(1))
       .and(Expression.property("timestamp")).lessThanOrEqualTo (Expression.longValue(1))
                    )
            )
 

И теперь результат действительно странный, так как я получаю три элемента из базы данных. И третий имеет timestamp гораздо больше, чем 1 указано в запросе.

 4e39f79c-9e11-4aba-9fb6-95d910f46cd9|0|-2147483648
e95646ee-ba3a-4978-b2a8-5383f31be2f1|0|-2147483648
e02d0eb3-6c9b-4942-b43c-a752eefc77a8|1630525956184|2147483647
 

Есть идеи, как заставить его работать с несколькими and() ? Если я попытаюсь удалить второй and() и сохранить третий, все будет работать так, как ожидалось.

Ответ №1:

После глубоких исследований я обнаружил несколько проблем в своем коде:

  • .and() следует вызывать в конце условия «ребенок», а не на уровне «родитель».

Для таких условий, как это

 val condition1 = Expression.property("type").equalTo(Expression.string(DOC_TYPE))
val condition2 = Expression.property("rating").lessThan(Expression.intValue(1))
val condition3 = Expression.property("timestamp")).lessThanOrEqualTo (Expression.longValue(1))

 

Правильный путь-это

 .where(condition1.and(
            condition2.and(
                condition3.and(
                    ...
                )
            )
        )
 

но не так, как я пытался

 .where(condition1.and(condition2)
                 .and(condition3)
                 .and(...)
      )
 
  • Для создания объекта я использовал код, который преобразует объект в Map<String, Any> перед сохранением в couchbase. Все, казалось, было в порядке, пока я не понял, что Long это было преобразовано в Double .
  • Последний момент, у меня очень сложные запросы, и внутри одного из них я случайно использовал .add() вместо .and() . Без комментариев.

Надеюсь, это поможет кому-нибудь сэкономить немного времени.

Ответ №2:

Я ожидал бы, что запрос будет таким, как вы сделали изначально:

.где(условие1.и(условие2) .и(условие3) .и(…))

Я думаю, что здесь есть дополнительная скобка, которая кажется неправильной:

.и(Выражение.свойство(«метка времени»))