【问题标题】:search element in flutter by mapped field通过映射字段​​在颤动中搜索元素
【发布时间】:2021-07-16 16:54:42
【问题描述】:

我有一个简单的菜肴集合,对于每一个我都有一份配料清单。

我想搜索所有具有特定成分的菜肴,但如果我写了一个成分,我可以检索多个成分。 例如,想象一下,我有 3 个带有油成分的菜肴,但我可以有不同的油(特级初榨、花生……),所以当我写 OIL 时,我必须检索所有带有所有类型油的菜肴。

我有一份菜品清单,每道菜由以下人员组成:

dish_1-->
|       |-->name: name_1
|       |-->ingredients -->
|                         |--> 1 --> 
|                                  |-->id:1
|                                  |-->name: Extra Virgin Oil
|                         |--> 3 --> 
|                                  |-->id:3
|                                  |-->name: Pasta
|
dish_2-->
|       |-->name: name_2
|       |-->ingredients -->
|                         |--> 2 --> 
|                                  |-->id:2
|                                  |-->name: Peanut Oil
|                         |--> 3 --> 
|                                  |-->id:4
|                                  |-->name: Tomato

我使用了模型 - 助手 - 提供者,我的想法是从成分集合中检索所有带有“油”的成分 ID,然后通过这些 ID 进行查询。 在我的 disc_helpers 中我写道:

Future<List<DishModel>> searchDishByIngredient({String ingredient}) {
    String searchKey = ingredient[0].toUpperCase() + ingredient.substring(1);
    List<DishModel> dishes = [];
    return _firestore.collection(subcollection).orderBy("name").startAt([searchKey]).endAt(
        [searchKey + '\uf8ff']).get().then((result) {
  for (DocumentSnapshot ingredient in result.docs) {
        _firestore.collection(collection).where("ingredients."+ingredient.id.toString()+".id",isEqualTo: int.parse(ingredient.id) ).get().then((result) {
          for (DocumentSnapshot dish in result.docs) {
            dishes.add(DishModel.fromSnapshot(dish));
            print("Length: " + dishes.length.toString());
          }
        });
      }
      return dishes;
    });
  }

和菜提供者

Future searchByIngredient({String ingredientName}) async {
    dishesSearched = await _dishServices.searchDishByIngredient(ingredient: ingredientName);
    notifyListeners();
  }

当我按成分搜索时,我总是得到一个空列表,但在控制台中我得到:“长度:2”。

为了了解我错过了什么,我变得疯狂

谁能帮帮我?

接受其他搜索方式。

谢谢

【问题讨论】:

  • 在填充列表之前,您可能会退回空盘子。尝试在您退回之前打印盘子并告诉我结果。
  • 我得到0长度,可能是你说的,我怎么解决? @lrsvmb

标签: firebase flutter dart mobile google-cloud-firestore


【解决方案1】:

看起来您将 get 调用返回到集合而不是 List 本身。我建议编写这样的代码:

Future<List<DishModel>> searchDishByIngredient({String ingredient}) async {
  String searchKey = ingredient[0].toUpperCase() + ingredient.substring(1);
  List<DishModel> dishes = [];

  dynamic result = await _firestore
      .collection(subcollection)
      .orderBy("name")
      .startAt([searchKey]).endAt([searchKey + '\uf8ff']).get();

  for (DocumentSnapshot ingredient in result.docs) {
    dynamic result2 = await _firestore
        .collection(collection)
        .where("ingredients." + ingredient.id.toString() + ".id",
            isEqualTo: int.parse(ingredient.id))
        .get();

    for (DocumentSnapshot dish in result2.docs) {
      dishes.add(DishModel.fromSnapshot(dish));
      print("Length: " + dishes.length.toString());
    }
  }

  return dishes;
}

在您的代码 sn-p 中,将执行获取集合的异步调用并按照您的解释记录数据,但您不会得到您期望的 List,因为它会为您返回 Future get 收藏。

【讨论】:

  • 它似乎有效!太好了,我明白错误了!
【解决方案2】:

看起来您是在填充列表之前退回菜肴。这是因为 for 循环中包含异步调用 (then()) 并在您返回盘子后完成。
解决方案是简单地使用 Future.forEach 并等待执行。也不需要返回 .then() 回调,因为你可以等待它。

Future<List<DishModel>> searchDishByIngredient({String ingredient}) async {
    String searchKey = ingredient[0].toUpperCase() + ingredient.substring(1);
    List<DishModel> dishes = [];
    var result = await _firestore.collection(subcollection).orderBy("name").startAt([searchKey]).endAt([searchKey + '\uf8ff']).get();    
    await Future.forEach(result.docs, (DocumentSnapshot ingredient) {
      _firestore.collection(collection).where("ingredients." + ingredient.id.toString() + ".id",isEqualTo: int.parse(ingredient.id)).get().then((result) {
        for (DocumentSnapshot dish in result.docs) {
          dishes.add(DishModel.fromSnapshot(dish));
          print("Length: " + dishes.length.toString());
        }
      });
    });
    return dishes;
  }

【讨论】:

  • I 与菜肴类型有关的错误,它无法返回未来类型的 List 方法
  • 既然这个问题已经回答了,我更新了我的答案给其他人:)
猜你喜欢
  • 2016-02-20
  • 2019-12-08
  • 1970-01-01
  • 2019-02-05
  • 2017-05-25
  • 2022-11-03
  • 2020-04-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多