如何在Algolia中显示带计数的分面(Facet)
问题:Algolia searchResponse.facets 始终为空
我正尝试获取已配置的分面列表,配置方式参考Algolia官方文档。我同时使用了Algolia新官方包和非官方包进行设置,原本以为官方包会改变响应结果。尽管浏览器控制台中一切看似符合预期,但searchResponse.facets始终为空。相关代码如下:
import 'dart:async'; import 'dart:io'; import 'package:algolia/algolia.dart'; import 'package:algolia_helper_flutter/algolia_helper_flutter.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:masterecommerce/src/constants/app_sizes.dart'; import 'package:masterecommerce/src/exceptions/app_exception.dart'; import 'package:masterecommerce/src/features/menu/presentation/search_header.dart'; import 'package:masterecommerce/src/features/products/domain/algolia_output.dart'; import 'package:masterecommerce/src/features/products/domain/algolia_params.dart'; import '../constants/credentials.dart'; import '../features/products/domain/product.dart'; import 'firestore_service.dart'; final searchResponseProvider = StateProvider.autoDispose<SearchResponse>((ref) { return SearchResponse({}); }); final searchStateProvider = StateProvider.autoDispose<SearchState>((ref) { return const SearchState(indexName: kIndexName); }); final algoliaInputProvider = StateProvider.autoDispose<AlgoliaInput>((ref) { return const AlgoliaInput(); }); final algoliaControllerProvider = StateNotifierProvider.autoDispose< AlgoliaController, AsyncValue<List<Product>>>((ref) { return AlgoliaController( ref: ref, algoliaInput: ref.watch(algoliaInputProvider)); }); final algoliaControllerSearchProvider = StateNotifierProvider.autoDispose< AlgoliaController, AsyncValue<List<Product>>>((ref) { return AlgoliaController( ref: ref, algoliaInput: AlgoliaInput( query: ref.watch(currentQuerySearchProvider), hitsPerPage: 3)); }); class AlgoliaController extends StateNotifier<AsyncValue<List<Product>>> { StreamSubscription? subResponses; StreamSubscription? subSearchState; late HitsSearcher searcher; late Algolia algoliaForSettings; final Ref ref; final AlgoliaInput algoliaInput; AlgoliaController({required this.ref, required this.algoliaInput}) : super(const AsyncLoading()) { algoliaForSettings = const Algolia.init( applicationId: algoliaKeyAppId, apiKey: algoliaKeyCustom); searcher = HitsSearcher( applicationID: algoliaKeyAppId, apiKey: algoliaKeyCustom, indexName: kIndexName, ); subResponses = searcher.responses.handleError((onError) { print(onError); state = AsyncError(onError); }).listen((searchResponse) { print(searchResponse.facets); print(searchResponse.raw["facets"]); ref.read(searchResponseProvider.state).update((state) => searchResponse); final products = searchResponse.hits .map((e) => Product.fromMapAlgolia(e.cast())) .toList(); if (mounted) { state = AsyncValue<List<Product>>.data(products); } }); subSearchState = searcher.state.handleError((onError) { print(onError); state = AsyncError(onError); }).listen((searchState) { ref.read(searchStateProvider.state).update((state) => searchState); }); _newAlgoliaState(algoliaInput: algoliaInput); } @override void dispose() { searcher.dispose(); subResponses?.cancel(); subSearchState?.cancel(); super.dispose(); } Future<void> _newAlgoliaState({required AlgoliaInput algoliaInput}) async { state = const AsyncLoading(); final algoliaOutput = algoliaInput.toAlgoliaOutput(); await _setAlgoliaRanking(algoliaOutput: algoliaOutput); if (!mounted) { return; } searcher.connectFilterState(algoliaOutput.filterState); searcher.applyState((state) => algoliaOutput.toSearchState()); } Future<void> _setAlgoliaRanking( {required AlgoliaOutput algoliaOutput}) async { AlgoliaIndexReference algoliaIndexReference = algoliaForSettings.instance.index("products"); final ranking = algoliaOutput.ranking; if (ranking != null && ranking.isNotEmpty) { AlgoliaTask algoliaTask = await algoliaIndexReference.settings.setRanking([ ...ranking, "typo", "geo", "words", "filters", "proximity", "attribute", "exact", "custom", ]).setSettings(); await algoliaTask .waitTask() .timeout(const Duration(seconds: timeOutSecond)) .catchError((onError) { if (onError is SocketException) { throw const AppException.noInternet(); } else if (onError is TimeoutException) { throw const AppException.timeOut(); } else { throw const AppException.unknown(); } }); } final customRanking = algoliaOutput.customRanking; if (customRanking != null && customRanking.isNotEmpty) { final AlgoliaTask algoliaTask = await algoliaIndexReference.settings .setCustomRanking(customRanking) .setSettings(); await algoliaTask .waitTask() .timeout(const Duration(seconds: timeOutSecond)) .catchError((onError) { if (onError is SocketException) { throw const AppException.noInternet(); } else if (onError is TimeoutException) { throw const AppException.timeOut(); } else { throw const AppException.unknown(); } }); } } }
内容的提问来源于stack exchange,提问作者mario francois
相关产品推荐
相关产品推荐

