前提・実現したいこと
swift
1struct Box { 2 let fruits: [Fruit] 3// 以下略 4} 5 6struct Fruit { 7 let type: String // "みかん" "りんご" など 8// 以下略 9}
上のような構造体Boxが入ったドキュメントのコレクションboxesを作成しました。
タイプが"みかん"のフルーツを含むBoxのリストを取得したいのですが、うまくいきません。
試したこと
swift
1let DB = Firestore.firestore() 2DB.collection("boxes").whereField("fruits.type", arrayContains: "みかん").getDocuments() 3DB.collection("boxes").whereField("fruits.type", isEqualTo: "みかん").getDocuments() 4DB.collection("boxes").whereField("fruits.`${index}`.type", isEqualTo: "みかん").getDocuments() 5DB.collection("boxes").whereField("fruits", arrayContains: "type.みかん").getDocuments()
4つともクエリを打ち、URLでインデックスを作成し、再度クエリを打ったのですが、結果は空のドキュメント配列でした。
よろしくお願いいたします。
追記
上記は簡易的な例で、実際のアプリはもっと複雑なのですが、公開ができないので、テストアプリを作りました。
firestoreのスクショ
テストアプリのViewController(コードが雑なのはご容赦ください)
swift
1import UIKit 2import Firebase 3 4class ViewController: UIViewController { 5 6 let DB = Firestore.firestore() 7 8 override func viewDidLoad() { 9 super.viewDidLoad() 10 11 let b = UIButton(frame: CGRect(x: 100, y: 200, width: 100, height: 50)) 12 b.backgroundColor = .red 13 view.addSubview(b) 14 b.addTarget(self, action: #selector(tapRed), for: .touchUpInside) 15 16 let b2 = UIButton(frame: CGRect(x: 100, y: 300, width: 100, height: 50)) 17 b2.backgroundColor = .blue 18 view.addSubview(b2) 19 b2.addTarget(self, action: #selector(tapBlue), for: .touchUpInside) 20 } 21 22 @objc func tapRed() { 23 let b = Box(name: "はこ1", fruits: [Fruit(type: "mikan"), Fruit(type: "apple")]).encoded() 24 let r = DB.collection("boxes").document("b1") 25 r.setData(b, completion: nil) 26 27 let b2 = Box(name: "はこ2", fruits: [Fruit(type: "apple")]).encoded() 28 let r2 = DB.collection("boxes").document("b2") 29 r2.setData(b2, completion: nil) 30 31 let b3 = Box(name: "はこ3", fruits: [Fruit(type: "mikan")]).encoded() 32 let r3 = DB.collection("boxes").document("b3") 33 r3.setData(b3, completion: nil) 34 } 35 36 @objc func tapBlue() { 37 // みかんの入った箱(b1とb3)だけ取りたい 38 let r = DB.collection("boxes").whereField("fruits", arrayContains: "type.mikan") 39 r.getDocuments() { (snap, error) in 40 print("結果", snap?.documents, error) 41 } 42 } 43} 44 45struct Box { 46 let name: String 47 let fruits: [Fruit] 48 49 func encoded() -> [String:Any] { 50 let fs = fruits.map({$0.encoded()}) 51 return ["name": name, "fruits": fs] 52 } 53} 54 55struct Fruit { 56 let type: String 57 func encoded() -> [String:Any] { 58 return ["type": type] 59 } 60}
どうしてもできない場合、fruitType配列をBoxに持たせようと思っていますが、ドキュメント内でデータが重複するので、できれば避けたいところです。
よろしくお願いいたします。
あなたの回答
tips
プレビュー