У меня проблема с условием запроса в Google Cloud Firestore.
Любой может мне помочь.
Ниже приведен мой код, чтобы первый документ начинался с HA_ и упорядочивался по ID DESC.
public Article getLastArticleProvider() {
ApiFuture<QuerySnapshot> query = firebaseDB.getTblArticles()
.whereGreaterThanOrEqualTo("articleId", "HA_")
.orderBy("id", Query.Direction.DESCENDING)
.limit(1)
.get();
QuerySnapshot snapshotApiFuture;
Article article = null;
try {
snapshotApiFuture = query.get();
List<QueryDocumentSnapshot> documents = snapshotApiFuture.getDocuments();
for (QueryDocumentSnapshot document : documents) {
article = document.toObject(Article.class);
}
} catch (InterruptedException | ExecutionException e) {
return null;
}
return article;
}
Я хочу получить последний идентификатор статьи, где articleId начинается с «HA_» или «XE_».
Пример для изображения выше:
Теперь я получаю сообщение об ошибке
java.util.concurrent.ExecutionException: com.google.api.gax.rpc.InvalidArgumentException: io.grpc.StatusRuntimeException: INVALID_ARGUMENT: inequality filter property and first sort order must be the same: articleId and id




Как говорит следующая ошибка:
inequality filter property and first sort order must be the same: articleId and id
Таким образом, вы не можете фильтровать свои элементы и сортировать их одновременно, используя разные свойства, в вашем случае articleId и id.
Так же есть пример как нет сделать это в официальная документация:
Фильтр диапазона и первый порядок по разным полям
citiesRef.whereGreaterThan("population", 100000).orderBy("country"); //Invalid
Поэтому, чтобы решить эту проблему, вы должны фильтровать и упорядочивать одно и то же свойство документа.
Я не уверен, что понимаю ваш вопрос. Предлагается не фильтровать и упорядочивать одно и то же свойство, потому что это невозможно, верно?
Извините за мой английский, но мне нужен результат, похожий на запрос sql: выберите * из статей, где articleId LIKE '%HA_%' упорядочить по идентификатору DESC limit 1
К сожалению, в путях Firestore к документам нет подстановочных знаков. Так что такого запроса не существует. Единственный вариант, который у вас есть, — использовать методы whereGreatedThan и whereLessThan.
Добавьте фиктивный порядок сразу после свойства фильтра неравенства и измените приоритет запроса в соответствии с вашими желаниями.
Я столкнулся с той же проблемой в javascript, но я считаю, что это также решение для java.
Когда я запускаю свой запрос:
module.exports.getLastGroupChat = async function (groupId) {
let colRef = db.collection('messages')
colRef = colRef.where('groupId', '==', groupId)
colRef = colRef.where('userId', '!=', '')
colRef = colRef.orderBy('timestamp', 'desc').limit(1)
const doc = await colRef.get()
return doc
}
И получил:
inequality filter property and first sort order must be the same: userId and timestamp
Чтобы решить эту проблему, прежде всего, мне пришлось добавить порядок сортировки того же свойства неравенства сразу после моего фильтра неравенства.
Кроме того, мне пришлось изменить приоритет запроса, чтобы добиться фиктивного порядка сортировки свойства неравенства.
Примечание: Вы можете запустить where -> order -> where -> order по тому же запросу!
module.exports.getLastGroupChat = async function (groupId) {
let colRef = db.collection('messages')
colRef = colRef.where('userId', '!=', '')
colRef = colRef.orderBy('userId', 'desc')
colRef = colRef.where('groupId', '==', groupId)
colRef = colRef.orderBy('timestamp', 'desc').limit(1)
const doc = await colRef.get()
return doc
}
Этот запрос отлично работал в моем локальном хранилище отладки. Внесите изменения в облачные функции Firebase и активируйте свою функцию. Проверьте свои журналы функций, вы можете получить ошибку индексации.
The query requires an index. You can create it here: https://console.firebase.google.com/v1/r/project...
Убедитесь, что вы попали по ссылке и создали индекс. Для вступления в силу потребуется от пяти до десяти минут. Затем запустите снова, вы работаете, и все должно быть в порядке.
Развлекайся! :)
Я попробовал ваше решение на Android, но двойное предложение where с разными полями не работает. Вы можете проверить это снова? Я думаю, что это сработало в вашем случае, потому что вы используете оператор "= = ". Ошибка: все, где фильтры с неравенством (notEqualTo, notIn, lessThan, lessThanOrEqualTo, GreatThan или GreatThanOrEqualTo) должны быть в одном поле. .whereGreaterThanOrEqualTo("current_date", timestamp) .orderBy("current_date", Query.Direction.DESCENDING) .whereNotEqualTo(country, 0) .orderBy(country)
Есть несколько (но важных) ограничений запросов firestore. Вы можете увидеть их все в следующей документации firebase.google.com/docs/firestore/query-data/queries. Используйте это в любое время, когда вы сталкиваетесь со сложными запросами.
В вашем случае вы комбинируете фильтры неравенства для разных полей в одном запросе, что не поддерживается firestore. Я действительно предлагаю вам прочитать документацию, которую я вам дал, она поможет вам понять ограничения запросов Firestore и, надеюсь, найти решение для вашего случая.
Я только что прочитал это вчера, теперь, к сожалению, возвращаюсь к MySQL.
Firestore имеет множество ограничений, из-за которых запросы становятся очень дорогими и неэффективными. Google сильно отстает от других облачных баз данных и полезен только при создании небольших фиктивных приложений для размещения в PlayStore.
возможно, firebase изменила ситуацию с тех пор, как был задан этот вопрос.
Ответ заключается в том, что вы МОЖЕТЕ выполнять фильтрацию и сортировку по разным полям.
вы можете связать порядок и фильтры, однако, если вы сначала фильтруете, вам нужно упорядочить по этому фильтру, прежде чем вы сможете упорядочить по любому другому полю. например
citiesRef.where('population', '>', 2500000).orderBy('population').orderBy('country');
Это в их документах. https://firebase.google.com/docs/firestore/query-data/order-limit-data#order_and_limit_data
However, if you have a filter with a range comparison (<, <=, >, >=), your first ordering must be on the same field, see the list of orderBy() limitations below.
вы можете связать orderBys разных полей, я только что сделал это по одному из своих запросов. (вы можете получить сообщение об ошибке при первом запуске, оно просит вас создать индекс, у него даже есть ссылка для создания индекса)
await db.collection('daily_equipments').where('date', '<', tomorrow._d).where('date', '>=', date).orderBy('date').orderBy('order','asc').get();
У вас есть предложения?