Boost.MultiIndex 数据结构内的通配符搜索?

发布于 2024-08-07 18:40:13 字数 1329 浏览 5 评论 0原文

我正在尝试通过减少数据库的往返来优化我的应用程序。作为这项工作的一部分,我已将一些表移动到内存中,将它们存储为 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;
}

但似乎进行通配符匹配的唯一方法是遍历整个结构并将每个键与提升进行比较::regex 与 boost::regex_match()。

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;
}

有更好的办法吗?

I'm trying to optimize my application by reducing round-trips to my database. As part of that effort, I've been moving some of the tables into memory, storing them asBoost.MultiIndex containers.

As a side-effect of this process, I've lost the ability to do wild-card matching on my strings. For example, when the table was stored in MySQL, I could do this:

SELECT * FROM m_table WHERE myString LIKE "foo%"

However, since I'm now using a Boost.MultiIndex container with a key of myString, it seems I've lost that ability.

Obviously, I can use the equal_range() function in order to find all entries that match a specific string exactly:

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;
}

But it seems like the only way to do a wild-card match is to walk the entire structure and compare each key to a boost::regex with boost::regex_match().

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;
}

Is there a better way?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

为人所爱 2024-08-14 18:40:13

好吧,首先你实际上不必使用 boost::regex,如果通配符足够简单,你可以通过滚动你自己的一元运算符来摆脱困境。我要指出的是,Boost.Regex 是库中实际需要链接的少数部分之一(不仅仅是头文件)。

至于遍历整个结构的问题,我很抱歉,但是如果您不知道提前进行的搜索,那么您在这里无能为力。

如果您事先知道要查找的参数,那么您可以创建适合使用专用比较器/哈希器执行此任务的多索引容器的特殊视图(例如,仅考虑第一个) 3 个字符)。

如果您希望获得更多信息,请提供有关您想要使用的通配符类型和情况的更多信息。

Well, first you don't actually have to use a boost::regex, if the wildcard is simple enough, you can get away by rolling you own unary operator. I would note that Boost.Regex is one of the few part of the library which actually requires to be linked (not header-only).

As for the problem of walking the whole structure, I am sorry but there is not much one can do you here... if you don't know the searches in advances.

If you know the parameters that you would be looking for in advance, then you can create a special view of the Multi-Index container suited to perform this task with a dedicated comparator/hasher (for example, one that only takes into account the first 3 characters).

If you were hoping for more, please provide more information regarding the kind of wildcards you want to use and the circumstances.

山有枢 2024-08-14 18:40:13

在您的具体情况下,您可以执行 lower_bound("foo"),然后向前寻找匹配项,直到遇到不匹配的内容或到达容器的末尾。但我认为没有通用的方法来进行此查找。

In your specific case, you can do a lower_bound("foo") and then walk forwards looking for matches, until you hit something that doesn't match or reach the end of the container. I don't think there is a general way to do this lookup though.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文