1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Firestoreが全文検索非対応なので、Swiftの力を使って全文検索できるようにしてみた

Last updated at Posted at 2024-01-11

はじめに

皆さん、明けましておめでとうございます! IPFactoryの筋肉大好きごみちゃんです:muscle:
今回は全文検索非対応のFirestoreをSwiftのライブラリの力を使って全文検索できるようにしてしまおうと言う記事です!
それでは早速いってみましょう!

レイアウト設置

今回は検索ワードを打ち込む用のTextFieldと検索ボタンだけ設置します!

コーディング

今回はFirestoreに登録してある本のタイトルを全文検索で取得する想定でコードを書いていきます。
Firestoreには事前に"Book"と言うコレクションの中に「ITパスポート」と言うワードが含まれている本を2冊登録しています。

それでは書いていきましょう!

まずはFirestoreをインポートして、インスタンスを定義しましょう。

import FirebaseFirestore
let db = Firestore.firestore()

次に各レイアウトの紐付けを行います。

    @IBOutlet weak var textField: UITextField!
    
    override func viewDidLoad() {
        super.viewDidLoad()

        
    }
    
    @IBAction func searchButton(_ sender: Any) {
        
    }

紐付けができたら、検索文字と該当した本のタイトルを格納する用の変数を定義します。

var bookNames = [""]

ここからは関数を書いていきます!

    //登録してあるすべての本の情報を受け取る
    func getAllBook(){
        db.collection("Book").getDocuments { querySnapshot, error in
            if let error = error {
                print("Error getting documents: \(error)")
                return
            }

            guard let querySnapshot = querySnapshot else {
                print("Error: querySnapshot is nil")
                return
            }
            
            for document in querySnapshot!.documents{
                var Title = document["title"] as! String
                self.searchBookTitle(Title: Title)
            }
        }
    }
    
    //全文検索を行なって検索文字が含まれている本のタイトルを配列に格納する
    func searchBookTitle(Title:String){
        var flg :Bool = Title.contains(textField.text!)
        if flg == true {
            bookNames.append(Title)
        }
    }

これで該当する本のタイトルを取得できました!

ここからはwhereField文を使って、先ほど取得した本のタイトルから本の情報を取得したいと思います。
本のタイトルと念の為、事前に登録してあった本の著者名も出力されるか試してみます。

//本の情報を出力する
    func printBookInfo(){
        db.collection("Book").whereField("title", in: bookNames).getDocuments { querySnapshot, error in
            if let error = error {
                print("Error getting documents: \(error)")
                return
            }

            guard let querySnapshot = querySnapshot else {
                print("Error: querySnapshot is nil")
                return
            }
            
            for data in querySnapshot!.documents {
                var title = data["title"] as! String
                var author  = data["author"] as! String
                print(title)
                print(author)
            }
        }
    }

先ほど書いた関数の中で今作ったprintBookInfo()が動作するようにgetAllBook()内に「printBookInfo()」と書き加えます。

    //登録してあるすべての本の情報を受け取る
    func getAllBook(){
        db.collection("Book").getDocuments { querySnapshot, error in
            if let error = error {
                print("Error getting documents: \(error)")
                return
            }

            guard let querySnapshot = querySnapshot else {
                print("Error: querySnapshot is nil")
                return
            }
            
            for document in querySnapshot!.documents{
                var Title = document["title"] as! String
                self.searchBookTitle(Title: Title)
            }
        }
        printBookInfo()
    }

ここまでできたらいよいよ関数を動かしてみます!
searchButtonが押されたらgetAllBook()が動くように「getAllBook()」と書き加えてください!

    @IBAction func searchButton(_ sender: Any) {
        getAllBook()
    }

これでコーディング終了です!
お疲れ様でした:bow_tone1:
ちゃんと動くかどうか試しにビルドしてみてください。

試しにビルドしてみたところうまくいきました!

コード全体

import UIKit
import FirebaseFirestore

class SearchWordViewController: UIViewController {
    
    let db = Firestore.firestore()
    var bookNames = [""]
    
    
    @IBOutlet weak var textField: UITextField!
    
    
    override func viewDidLoad() {
        super.viewDidLoad()

        
    }
    
    @IBAction func searchButton(_ sender: Any) {
        getAllBook()
    }
    
    //登録してあるすべての本の情報を受け取る
    func getAllBook(){
        db.collection("Book").getDocuments { querySnapshot, error in
            if let error = error {
                print("Error getting documents: \(error)")
                return
            }

            guard let querySnapshot = querySnapshot else {
                print("Error: querySnapshot is nil")
                return
            }
            
            for document in querySnapshot!.documents{
                var Title = document["title"] as! String
                self.searchBookTitle(Title: Title)
            }
        }
        printBookInfo()
    }
    
    //全文検索を行なって検索文字が含まれている本のタイトルを配列に格納する
    func searchBookTitle(Title:String){
        var flg :Bool = Title.contains(textField.text!)
        if flg == true {
            bookNames.append(Title)
        }
    }
    
    //本の情報を出力する
    func printBookInfo(){
        db.collection("Book").whereField("title", in: bookNames).getDocuments { querySnapshot, error in
            if let error = error {
                print("Error getting documents: \(error)")
                return
            }

            guard let querySnapshot = querySnapshot else {
                print("Error: querySnapshot is nil")
                return
            }
            
            for data in querySnapshot!.documents {
                var title = data["title"] as! String
                var author  = data["author"] as! String
                print(title)
                print(author)
            }
        }
    }
    
}

さいごに

今回はSwiftの力を使ってFirestoreに格納したデータを全文検索できるようにしてみました! 少しでも参考になれたなら嬉しいです :muscle:
まだまだプログラミング初心者なので至らない点も多かったかと思いますが、最後までご覧いただきありがとうございました:bow_tone1:
1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?