質問

データベースへのラウンドトリップを減らしてアプリケーションを最適化しようとしています。その取り組みの一環として、いくつかのテーブルをメモリに移動し、次のように保存しています。 Boost.MultiIndex コンテナ。

このプロセスの副作用として、文字列でワ​​イルドカード マッチングを実行できなくなりました。たとえば、テーブルが MySQL に保存されている場合は、次のようにすることができます。

SELECT * FROM m_table WHERE myString LIKE "foo%"

ただし、現在は myString のキーを持つ Boost.MultiIndex コンテナーを使用しているため、その機能が失われているようです。

明らかに、equal_range() 関数を使用して、特定の文字列に正確に一致するすべてのエントリを検索できます。

std::pair< typename T::template index<by_name>::type::iterator,
           typename T::template index<by_name>::type::iterator > p
  = m_table.get<by_name>().equal_range(myString);

while (p.first != p.second )
{
  // do something with the EXACT matching entry
  ++p.first;
}

しかし、ワイルドカードの一致を行う唯一の方法は、構造全体を調べて、boost::regex_match() を使用して各キーを boost::regex と比較することのようです。

std::pair< typename T::template index<by_name>::type::iterator,
           typename T::template index<by_name>::type::iterator > p
  = std::make_pair(m_table.get<by_name>().begin(),m_table.get<by_name>().end());

while (p.first != p.second )
{
  boost::regex e(myRegex);
  if ( boost::regex_match(p.first->myString, e ) )
  {
     // Do something with the REGEX matching entry
  }
  ++p.first;
}

もっと良い方法はありますか?

役に立ちましたか?

解決

まず、実際に boost::regex を使用する必要はありません。ワイルドカードが十分に単純であれば、独自の単項演算子をロールすることで回避できます。Boost.Regex は、(ヘッダーのみではなく) 実際にリンクする必要があるライブラリの数少ない部分の 1 つであることに注意してください。

建物全体を歩くという問題に関しては、申し訳ありませんが、ここでできることはあまりありません...事前に検索内容がわからない場合。

探しているパラメーターが事前にわかっている場合は、専用のコンパレーター/ハッシュ (たとえば、最初のパラメーターのみを考慮するビュー) を使用して、このタスクを実行するのに適したマルチインデックス コンテナーの特別なビューを作成できます。 3文字)。

さらに詳しい情報をご希望の場合は、使用したいワイルドカードの種類と状況に関する詳細情報を提供してください。

他のヒント

特定のケースでは、 lower_bound("foo") を実行し、一致しないものにヒットするかコンテナの最後に到達するまで、一致するものを探して前に進みます。ただし、この検索を行う一般的な方法はないと思います。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top