2016-12-15 74 views
1

我目前正在为iOS创建一个电子商务应用程序,而且我很难决定如何构建用户通过“关键字”搜索项目的场景的数据库。我不确定是否最好存储一个关键字数组或者只是为该项目设置一串关键字。Firebase数据库结构

如果你们有任何建议,请让我知道!

谢谢。

这里的结构我有一个单一的项目现在:

"items": { 
     "item1_id":{ 
      "brand_id": brandName_id, 
      "itemName":....., 
      "price":....., 
      "keywords": ? 
    } 
    } 
+1

你打算有基于关键字的查询? – cartant

+0

是的,我愿意!如果一个人想要搜索一个基于类似......的东西......“黑色,T恤,设计......“@cartant –

回答

2

在火力地堡,您可以查询使用单个值或值范围,所以构建一个查询以获得项目配套的几个关键词是不会成为可能。但是,您可以安排数据库,以便轻松查询或使用单个关键字。然后你需要几个查询组合等

你可以安排你这样的数据:

{ 
    "items": { 
    "item1_id": { 
     "brand_id": ..., 
     "itemName": ..., 
     "price": ..., 
     "keywords": { 
     "black": true, 
     "t-shirt": true 
     } 
    } 
    } 
} 

然而,如this answer解释,你需要定义为每个关键字的索引。为了能够有效的基于关键字的查询,您可以创建自己的关键字映射到项目:

{ 
    "items": { 
    "item1_id": { 
     "brand_id": ..., 
     "itemName": ..., 
     "price": ..., 
     "keywords": { 
     "black": true, 
     "t-shirt": true 
     } 
    } 
    }, 
    "keywords": { 
    "black": { 
     "item1_id": true 
    }, 
    "t-shirt": { 
     "item1_id": true 
    } 
    } 
} 

为关键字的查询将是这样的:

let keyword = "black"; 
database.ref(`keywords/${keyword}`).once("value", (snapshot) => { 
    snapshot.forEach((idSnapshot) => { 
    database.ref(`items/${idSnapshot.key}`).once("value", (itemSnapshot) => { 
     console.log(JSON.stringify(itemSnapshot.val())); 
    }); 
    }); 
}); 

有维护自己的关键字到项目的映射有点痛苦,但查询速度会很快。此外,Firebase的多位置更新可以使维护关键字映射更容易一些。要创建一个项目:

database.ref().update({ 
    "items/item1_id": { 
    "brand_id": ..., 
    "itemName": ..., 
    "price": ..., 
    "keywords": { 
     "black": true, 
     "t-shirt": true 
    } 
    }, 
    "keywords/black/item1_id": true, 
    "keywords/t-shirt/item1_id": true 
}); 

要更改项目的关键字(删除black,加blue离开t-shirt不变):

database.ref().update({ 
    "items/item1_id/keywords": { 
    "black": null, 
    "blue": true 
    }, 
    "keywords/black/item1_id": null, 
    "keywords/blue/item1_id": true 
}); 

并删除一个项目:

database.ref().update({ 
    "items/item1_id": null, 
    "keywords/blue/item1_id": null, 
    "keywords/t-shirt/item1_id": null 
}); 
+0

你需要在这个场景中为每个类别定义一个索引,替代方法是为'/ categories/$ category/item1:true'建模。参见http://stackoverflow.com/questions/40656589/ firebase-query-if-child-of-child-contain-a-value –

+0

谢谢,@FrankvanPuffelen。我已经重写了答案。 – cartant

+0

感谢cartant和@Frank van Puffelen我会试着将它融入我的iOS应用程序,我会给你一个更新! –

2

如何约:

items 
     item0 
     color: black 
     type: t-shirt 
     option: design 
     keywords: black_t-shirt_design 
     item1 
     color: black 
     type: hat 
     option: design 
     keywords: black_hat_design 

然后使用startingAt和endingAt进行简单的查询。

因此,例如,说用户使用过滤器来缩小结果,并希望有关知道所有的黑帽子和不关心的选项参数是什么:

itemsRef.queryOrdered(byChild: "keywords") 
     .queryStarting(atValue: "black_hat") 
     .queryEnding(atValue: "black_hat") 

同样,如果用户想知道所有只是黑色的衣服,你可以在“颜色”的孩子身上查询黑色。

但如果他们想所有的黑帽子与设计选项

itemsRef.queryOrdered(byChild: "keywords") 
     .queryStarting(atValue: "black_hat_design") 
     .queryEnding(atValue: "black_hat_design")