Я использую Статическое веб-приложение Azure с базой данных SQL Azure. При фильтрации данных я хочу использовать оператор in
вместо оператора eq
. Пока что оператор eq
работает как положено:
async function filterProducts() {
const query = `
query Products {
products(filter: { category: { eq: "dairy" } }) {
items {
date
category
price
}
}
}`;
const filteredProducts = await fetch('/data-api/graphql', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ query: query })
})
.then((response) => response.json())
.then((dataJson) => {
const dataItems = dataJson.data.products.items;
const dates = dataItems.map((product) => product.date);
const prices = dataItems.map((product) => product.price);
return { dates, prices };
})
.catch((err) => console.warn('Unable to fetch from the endpoint.', err));
return filteredProducts;
}
Однако использование оператора in
приведет к ошибке статуса 400 (неверный запрос). Это входной запрос:
const query = `
query Products {
products(filter: { category: { in: ["dairy", "fruit"] } }) {
items {
date
category
price
}
}
}`;
И я получил ошибку при вызове конечной точки localhost:4280/data-api/graphql
:
Не удалось загрузить ресурс: сервер ответил со статусом 400 (неверный запрос).
Можно ли использовать оператор in
из статического веб-приложения Azure? Как отфильтровать несколько значений с помощью GraphQL в статическом веб-приложении Azure?
@Sampath Я не использую пакет gatsby
. Я использую только строку запроса и отправляю ее в GraphQL API, который генерируется с помощью инструмента Azure Static Web App CLI.
какой инструмент вы использовали
@Sampath Я создал приложение Svelte.
Последний API REST Graph поддерживает $filter с условием. Пример URL-адреса для него будет выглядеть как ~/users?$filter=mail in ('[email protected]', '[email protected]')
. Надеюсь, вы сможете попробовать ("dairy", "fruit")
вместо ["молочные", "фруктовые"].
Рекомендации
Graph API — используйте параметр запроса фильтра
К сожалению, замена фильтра на ("dairy", "fruit")
не работает. Он возвращается с той же ошибкой. Я проверил схему GraphQL с помощью Postman, и она не содержит оператора in
.
@PéterSzilvási Я попробовал этот образец lucasconstantino.github.io/graphiql-online, и он сработал нормально. запрос стран { страны (фильтр: { имя: { in: ["Андорра", "Объединенные Арабские Эмираты"] } }) {имя } } Можете ли вы проверить, что вы получаете в err ? Я бы сказал, что запрос GraphQL выглядит нормально.
Я думаю, что существует ограничение на сервере GraphQL статического веб-приложения Azure.
После запуска статического веб-приложения (SWA) я исследовал схему GraphQL с помощью Postman. Поскольку я использую интерфейсную платформу Svelte, сервер разработки прослушивает порт 5000. Поэтому я указал http://localhost:5000/graphql
в URL-адресе, перешел на вкладку «Схема» и загрузил схему с помощью «Использование самоанализа GraphQL». Вернувшись на вкладку «Запрос», я могу выполнить поиск по доступным параметрам фильтрации:
Что касается API GraphQL статического веб-приложения, я не вижу параметров фильтрации in
. Можно проверить равенство, содержащее или начинающееся с условий, используя ввод одной строки.
Учитывая это ограничение, я реализовал обходной путь, используя список категорий с циклом for и параметр фильтрации eq
:
async function filterProducts() {
let result = [];
const categories = ['dairy', 'fruit'];
for (const category of categories) {
const query = `
query Products {
products(filter: { category: { eq: "${category}" } }) {
items {
date
category
price
}
}
}`;
const filteredProducts = await fetch('/data-api/graphql', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ query: query })
})
.then((response) => response.json())
.then((dataJson) => {
const dataItems = dataJson.data.products.items;
const dates = dataItems.map((product) => product.date);
const prices = dataItems.map((product) => product.price);
return { dates, prices };
})
.catch((err) => console.warn('Unable to fetch from the endpoint.', err));
result = result.concat(filteredProducts);
}
return result;
}
Он перебирает нужные категории, извлекает их из конечной точки API, а затем добавляет каждую категорию в массив результатов.
Примечание. Было бы неплохо использовать оператор
in
, но, поскольку у SWA есть свои ограничения, я думаю, «нам придется готовить из того, что есть».
Обновлено: Будьте осторожны, потому что API GraphQL (а также REST) извлекает данные в пакетном режиме. Размер пакета по умолчанию — 100, поэтому для получения всех данных необходим метод пагинации.
Ответ https://stackoverflow.com/a/78345944/10721627 является неполным, поскольку по умолчанию он извлекает только 100 данных. Чтобы собрать все данные, нам нужно использовать hasNextPage
в качестве оператора возврата и переназначать afterCursor
переменной endCursor
на каждой итерации.
async function filterProducts() {
let allProducts = [];
let pageSize = 1000;
let hasNextPage = true;
let afterCursor = null;
// Fetches all data from the endpoint using pagination.
while (hasNextPage) {
const query = `
query Products {
products(first: ${pageSize}, after: ${afterCursor}) {
items {
date
category
price
}
hasNextPage
endCursor
}
}
`;
await fetch('/data-api/graphql', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ query: query })
})
.then((response) => response.json())
.then((dataJson) => {
allProducts = allProducts.concat(dataJson.data.products.items);
hasNextPage = dataJson.data.products.hasNextPage;
afterCursor = `"${dataJson.data.products.endCursor}"`;
})
.catch((err) => {
console.warn('Unable to fetch the data from the `selectAllMaterialStock` endpoint.', err);
hasNextPage = false;
});
}
// Filters the data using the fields.
const categories = ['dairy', 'fruits'];
const filteredProducts = allProducts.filter((item) => categories.includes(item.category));
return filteredProducts;
}
Мы добавляем полученные данные в массив allProducts
. Получив полные данные, мы можем отфильтровать их с помощью встроенного метода Array.prototype.filter(), поскольку оператор in
использовать нельзя, см. предыдущий ответ.
Примечание. Если данных очень много, это решение не будет самой эффективной альтернативой. Возможная альтернатива — использовать пакет
mssql
для прямого запроса к базе данных.
используют GraphQL и Gatsby