【问题标题】:Searching dataset by multiple tags通过多个标签搜索数据集
【发布时间】:2017-12-13 04:39:43
【问题描述】:

也许这个问题的标题有点奇怪,因为我根本不知道我在找什么。

我有一些数据,例如一个字符串和多个与之关联的标签。现在我希望能够使用字符串搜索我的数据。

编辑:问题不在于字符串比较或子字符串 搜索! 问题是从结果到数据的连接 对象。

这里是电影示例:

"Title1" tags: "genre1" "genre2" "actor1" "actor2"
"Title2" tags: "genre2" "actor2" "actor3"
"Title3" tags: "genre2" "genre3" "actor1" "actor3"

Search for "genre2" -> "Title1", "Title2", "Title3"
Search for "Title1" -> "Title1"
Serach for "actor1" -> "Title1", "Title3"

其他例子:

  • YouTube:搜索视频...
  • 亚马逊:搜索“tv”,但“tv”不必出现在标题中。

我唯一想到的是一个指向所有可能性列表的多图。然后我必须将搜索字符串与所有键和 tada 进行比较。但我不敢相信这是一个好的解决方案,因为我会有大量的列表......

谁能告诉我我在寻找什么以及如何实现它?我将 c++ 与 Qt 一起使用。我不知道 Qt 是否能以任何方式帮助我。

编辑:我可以像这样将所有关键字添加在一起:

"Title1 genre1 genre2 actor1 actor2"
"Title2 genre2 actor2 actor3"
"Title3 genre2 genre3 actor1 actor3"

用这个键创建一个映射到数据对象。然后我只需要进行字符串搜索并获取搜索字符串是键的子字符串的所有字符串。

但这是一个好的解决方案吗?如果我想在标题中优先匹配匹配怎么办?

【问题讨论】:

  • 您考虑过实际的数据库吗?也许是 sqlite?
  • @RetiredNinja 是的,但目前我不确定是否需要。
  • 我认为解决这个问题的最佳方法是suffix treesuffix array。如果您使用suffix tree,请使用与叶子中的字符串对应的所有标题的索引列表。
  • @abdullah 嗯,我调查了它,但看起来这只会帮助我检测到这样的东西:“ctor”->“actor1”、“actor2”、“actor3”。但最后,我想在这种情况下拥有所有 3 个标题。还是仅将标签的完全匹配视为标签搜索而将所有其他标签视为标题搜索更好?
  • @Darkproduct 你应该测试完全匹配

标签: c++ qt search


【解决方案1】:

如果它有很多数据,或者您希望将数据迁移到另一台计算机,我会使用 Qt 的内置 SQL 功能。

【讨论】:

  • 我不希望将数据传输到另一台计算机,因为它只是本地文件系统中其他数据的集合。
【解决方案2】:

几个月后,我决定再次解决这个问题,最后,我找到了解决方案。我花了 ~ 4 小时才让一切正常工作。我现在在 Qt 中使用带有 SQLite 的 Toxi-Tagging。我从this post 得到了这个想法,并且还研究了其他可能性。这是一个包含多个选项和一个小比较的页面:Link

这是我的解决方案: 创建数据库并向其添加值。然后你可以像这样进行简单的子字符串搜索:

SELECT Data.* FROM Data 
INNER JOIN DataTag ON DataTag.DataID=Data.ID 
INNER JOIN Tag ON DataTag.TagID=Tag.ID WHERE Tag.Tag LIKE "%substring%" 
GROUP BY Data.ID

旁注:如果您的标签列表非常大,使用 FTS3 或 FTS4 可能会有所帮助。这是more info

创建数据库:

QString scom;
QSqlQuery query;

scom = "CREATE TABLE Data ("
       "ID INTEGER PRIMARY KEY,"
       "Data1 VARCHAR(120) NOT NULL UNIQUE,"
       "Data2 INTEGER NOT NULL,"
       "Data3 INTEGER NOT NULL);";

if(!query.exec(scom))
{
    qDebug() << "Error creating table Data";
}

scom = "CREATE TABLE Tag ("
       "ID INTEGER PRIMARY KEY,"
       "Tag VARCHAR(120) NOT NULL UNIQUE);";

if(!query.exec(scom))
{
    qDebug() << "Error creating table Tag";
}

scom = "CREATE TABLE DataTag ("
       "DataID INTEGER,"
       "TagID INTEGER,"
       "FOREIGN KEY(DataID) REFERENCES Data(ID)"
       "FOREIGN KEY(TagID) REFERENCES Tag(ID));";

if(!query.exec(scom))
{
    qDebug() << "Error creating table DataTag";
}

scom = "CREATE UNIQUE INDEX index_name ON Tag (Tag)";

if(!query.exec(scom))
{
    qDebug() << "Error could not create index on Tag Tag";
}

向数据库添加值:

QString scomadddata, scomaddtag, scomadddatatag, scomsearchtag;
QSqlQuery query;

scomadddata = "INSERT INTO Data (ID, Data1, Data2, Data3) "
              "VALUES (NULL, ?, ?, ?)";

query.prepare(scomadddata);
query.addBindValue(data1);
query.addBindValue(data2);
query.addBindValue(data3);

if(!query.exec())
{
    qDebug() << "Error adding values to Data";
    qDebug() << query.lastError();
}

QVariant dataid = query.lastInsertId();

scomsearchtag = "SELECT ID FROM Tag WHERE Tag = ";
scomaddtag = "INSERT INTO Tag (ID, Tag) VALUES (NULL, ?)";
scomadddatatag = "INSERT INTO DataTag (DataID, TagID) VALUES (?, ?)";

for(int i = 0; i < tags.count(); ++i)
{
    QVariant tagid;

    // Search if Tag allready exists
    if(!query.exec(scomsearchtag + "\"" + tags[i] + "\""))
    {
        qDebug() << "Error searching for Tag";
        qDebug() << query.lastError();
    }

    if(query.next())
    {
        tagid = query.value(0);
    }
    else
    {
        // Add Tag to Tag Table
        query.prepare(scomaddtag);
        query.addBindValue(tags[i]);

        if(!query.exec())
        {
            qDebug() << "Error adding values to Tag";
            qDebug() << query.lastError();
            continue;
        }

        // Get Tag ID
        tagid = query.lastInsertId();
    }

    // Link Tag ID with Data ID
    query.prepare(scomadddatatag);
    query.addBindValue(dataid);
    query.addBindValue(tagid);

    if(!query.exec())
    {
        qDebug() << "Error adding values to DataTag";
        qDebug() << query.lastError();
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-21
    相关资源
    最近更新 更多