欲しいアプリは自分で作る!

Power Platform や Azure などを利用して作成した業務アプリや趣味アプリなどをご紹介します。

Power Apps で Google 検索のような複数ワードの部分一致 OR 検索を行う方法

(2020/10/02)
キーワード数に依存しない記述方法を補足に追記しました。



G〇〇gle 検索のようなものを作ります(見た目的な意味で)。




どうも、じゅんじゅんです。


先日より Teams 上で Power Apps アプリが作成できるようになり、Search 関数を用いた文字列の部分一致検索ができるようになりました。 jn.hateblo.jp

これを機に、検索機能を持ったナレッジ共有アプリを作る方が増えるのではないかと勝手に予想しております。


ということで、せっかくなので日頃よくお世話になっている某検索サイトのように、複数のキーワードをスペース区切りで OR 検索(あるいは AND 検索)できると便利だなと思い、作ってみました。
(以下動画は Teams + Power Apps ではないですが、Teams + Power Apps でも同じことができます)


目次


まずはデータと検索窓の用意まで

前回の記事の "事前準備" まで行います(以下参照)。 https://jn.hateblo.jp/entry/2020/09/26/164959#%E4%BA%8B%E5%89%8D%E6%BA%96%E5%82%99

今回は、"AND_OR検索" というテーブルを作成し、既存の "件名" 列に今食べたいものを登録してみました。 f:id:jn-kodama:20200930205339p:plain

そして、画面の上部あたりにテキストボックスを挿入しておきます。 f:id:jn-kodama:20200930205715p:plain

こんな感じで検索ワードを入れたら、下部の Gallery をフィルタリングできるようにします。 f:id:jn-kodama:20200930205859p:plain


フィルタリングで複数キーワードの部分一致 OR 検索を実現する方法(固定ワード編)

実は前回の記事で、部分一致には Search 関数が使えることをご紹介しました。

Search 関数は、1 つの関数で検索したい列を複数指定できるというメリットがある一方で、Search 関数 1 つで複数ワードの検索はできないため、Search 関数で複数ワードの検索を実現するには Search 関数をネストする必要があります。
参考: 複数キーワードによる検索 - Japan Power Platform User Group コミュニティサイト

そこで今回は、部分一致検索ができるもう一つの方法として、in 句を使用します。


in 句は、Filter 関数内で

Filter(テーブル名, "検索したいキーワード" in 検索したい列名)

と記載することで、検索したい列の中に検索したいキーワードが含まれるレコードを抽出してくれるものです。
※列名は右辺です。列名を左辺に書くと警告が出て正常に機能しませんのでご注意ください。

以下はキーワード:"焼" で検索する場合の記述方法 f:id:jn-kodama:20200930212120p:plain

なお、Search 関数で

Search(テーブル名, "検索したいキーワード", "検索したい列名")

と記載すると、先ほどの Filter と同じ結果が得られます。
(ただし Search 関数の列名は二重引用符で囲まれている必要がある点に注意)


さて、本題です。

Filter 関数では、検索に複数の条件を指定することができます。 早速、条件を追加してみましょう。

Filter(AND_OR検索, "焼" in 件名, "牡蠣" in 件名)

f:id:jn-kodama:20200930212317p:plain

"焼き牡蠣" だけ残りました。
Filter 関数で指定した複数の条件は、AND 検索となるのです。

そこで、これを OR 検索に置き換えます。
OR 検索にするには、複数の条件を Or 関数で囲えば OK です。
(r が小文字であることに注意)

Filter(AND_OR検索, 
    Or(
        "焼" in 件名,
        "牡蠣" in 件名
    )
)

f:id:jn-kodama:20200930213305p:plain

無事、"焼" または "牡蠣" が含まれるレコードが抽出できました。


複数キーワードの部分一致 OR 検索ができたところで、このキーワードを最初に用意した検索窓(テキストボックス)から抽出する方法について考えます。


検索窓から複数のキーワードを抽出する方法

ここでは、2つの工程に分けて考えます。

  1. テキストボックスの値をスペースで分割する(分割された各キーワードが格納されたテーブルになる)
  2. 1.のテーブルから1つずつキーワードを抜き出す


1. テキストボックスの値をスペースで分割する

ここでは、Split 関数を利用します。
Split 関数 - Power Apps | Microsoft Docs

テキストボックスに "焼 牡蠣" と記載されている場合(半角スペース区切り)、

Split(テキストボックス名.Value, " ")

と書くと、

Result
牡蠣

というテーブルが取得できます。


2. 1.のテーブルから1つずつキーワードを抜き出す

ここでは、FirstN 関数と Last 関数を利用します。

これは、Qiita の Power Apps タグで不動の1位を誇るやまさん (@yamad365) の以下の記事がすべてですので、ご一読ください。
qiita.com


これを踏まえて。


テキストボックスに記載されたキーワードの N 個目は、以下のように表すことができます。

// 1個目
Last(FirstN(Split(テキストボックス名.Value, " "), 1)).Result
// 2個目
Last(FirstN(Split(テキストボックス名.Value, " "), 2)).Result
// 3個目
Last(FirstN(Split(テキストボックス名.Value, " "), 3)).Result
...

f:id:jn-kodama:20200930223509p:plain


フィルタリングで複数キーワードの部分一致 OR 検索を実現する方法(検索窓を利用編)

これまでの内容を組み合わせて、検索窓(テキストボックス)から複数のキーワードを抽出して部分一致 OR 検索を行います。

ただ、検索窓にいくつキーワードが入力されるかが分からないため、Filter 関数をどのように書いたらよいか分からないですよね。


ということで、ちょっと実験。


試しに5つのキーワードを抽出できる用意をし、5つ未満のキーワードを入力した場合にどのような値が抽出できるかを試してみます。
まずは、5つのキーワードを入力した状態。

f:id:jn-kodama:20200930224215p:plain

キーワードを1つ減らしてみます。

f:id:jn-kodama:20200930224353p:plain

おや?

f:id:jn-kodama:20200930224541p:plain

どうやら、FirstN 関数で指定した位置がテーブルの値の個数を超えた場合は、一番最後の値になるようです。

同じ値で OR 検索しても結果に変わりはないはずなので(例えば「焼 焼」と検索しても、結果は「焼」を検索した結果になる)、この方法は使えそうです。


ということで、これを Filter 関数に適用すると、以下のようになります。

Filter(AND_OR検索, 
    Or(
        Last(FirstN(Split(Microsoft_CoreControls_TextBox2.Value, " "), 1)).Result in 件名,
        Last(FirstN(Split(Microsoft_CoreControls_TextBox2.Value, " "), 2)).Result in 件名,
        Last(FirstN(Split(Microsoft_CoreControls_TextBox2.Value, " "), 3)).Result in 件名,
        Last(FirstN(Split(Microsoft_CoreControls_TextBox2.Value, " "), 4)).Result in 件名,
        Last(FirstN(Split(Microsoft_CoreControls_TextBox2.Value, " "), 5)).Result in 件名
    )
)

f:id:jn-kodama:20200930225304p:plain

f:id:jn-kodama:20200930225518p:plain

これで、5つまでのキーワードはこの記載で対応できます。


補足

AND 検索と併用したい方は、トグルスイッチなどを追加し、そのスイッチの値に応じて Filter 処理を分岐するとよいです(あまりスマートではありませんが。。)。

f:id:jn-kodama:20200930230607p:plain


全角と半角のスペース両方に対応させたい場合は、どちらかに置換してから Split しましょう。(以下は全角スペースを半角スペースに置換してから Split する例)。

Split(Substitute(テキストボックス名.Value, " ", " "), " ")

参考:Replace および Substitute 関数 - Power Apps | Microsoft Docs


Gallery の Items の書き方を工夫すると、キーワード数に依存しないフィルタリングができるようになります(下図参照)。
(Hiro さん、アドバイスいただきありがとうございます!)

f:id:jn-kodama:20201002180924p:plain


おわりに

Power Apps で Google 検索のような複数ワードの部分一致 OR 検索を行う方法をご紹介しました。

普段慣れ親しんでいる UI に近づけるというのは、利用ユーザーの操作負担を減らすのに効果的だと思いますので、是非チャレンジしてみてください。



欲しいアプリは欲しい人が作る時代へ。
何かヒントになれば幸いです。


参考文献

qiita.com

power.users.community

docs.microsoft.com

docs.microsoft.com

qiita.com