Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/401.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何将标记映射到标记同义词?_Javascript_Mysql_Sql_Node.js_Node Mysql - Fatal编程技术网

Javascript 如何将标记映射到标记同义词?

Javascript 如何将标记映射到标记同义词?,javascript,mysql,sql,node.js,node-mysql,Javascript,Mysql,Sql,Node.js,Node Mysql,我正在构建一个系统,用户可以将标签与帖子联系起来,这与此类似。我执行起来有点麻烦 这里有一个名为标签的表格: | TagName | |------------| | Python | | JavaScript | | Node | | SynonymId | SourceTagName | TargetTagName | |-----------|---------------|---------------| | 1 | Py

我正在构建一个系统,用户可以将标签与帖子联系起来,这与此类似。我执行起来有点麻烦

这里有一个名为标签的表格:

| TagName    |
|------------|
| Python     |
| JavaScript |
| Node       |
| SynonymId | SourceTagName | TargetTagName |
|-----------|---------------|---------------|
| 1         | Py            | Python        |
| 2         | Python2       | Python        |
我还有另一个名字叫“同义词”:

| TagName    |
|------------|
| Python     |
| JavaScript |
| Node       |
| SynonymId | SourceTagName | TargetTagName |
|-----------|---------------|---------------|
| 1         | Py            | Python        |
| 2         | Python2       | Python        |
服务器使用节点实现,用户以逗号分隔的字符串形式输入一些标记:

var input = 'Py,Flask'
var tags = request.tags.split(',');
在这种情况下,用户输入了标记Py,根据TagSynonyms表,该标记应映射到标记Python。第二个标记,Flask没有同义词,应该保持不变

我使用命令式代码实现了此功能:

tags.forEach(function (tag) {
  connection.query('SELECT TargetTagName FROM TagSynonyms WHERE SourceTagName = ?', tag, function(err, rows) {
    if (rows.length !== 0) {
      console.log(rows[0].TargetTagName);
    } else {
      console.log(tag);
    }
  });
});
这里,用户输入

['Py','Flask'] 
结果如下所示:

Python
Flask

我想做的是,将此逻辑推迟到数据库引擎,因为我认为使用循环是一种代码味道。我还认为数据库引擎的性能会更好。什么是执行此操作的适当查询?

您需要一个
联合和一个联接:

  select TagName
    from Tags
    where TagName in (?,?,?,...)
union
  select TagName
    from Tags
    join TagSynonyms
      on Tags.TagName = TagSynonyms.TargetTagName
    where TagSynonyms.SourceTagName in (?,?,?,...)
请注意,
union
可能会很慢,因为它会尝试删除重复项。如果是这种情况,请使用
union all
并删除应用程序代码中的重复项

(?,?,?,…)
表示输入值列表;查看DB驱动程序文档,了解避免SQL注入所需的确切语法

更新:以下是节点中的实现:

var query = 
'SELECT TagName \
FROM Tags \
WHERE TagName IN (?) \
UNION \
SELECT TagName \
FROM Tags \
JOIN TagSynonyms \
  ON Tags.TagName = TagSynonyms.TargetTagName \
WHERE TagSynonyms.SourceTagName IN (?)'

connection.query(query, [tags, tags], function(err, rows) {
  tags = rows.map(function(row) { 
    return row.TagName
  });
});

您只需从标记同义词中选择TargetTagName,其中SourceTagName在?中,标记
,即可在一个QuerySynymid中从DB中选择所有值redundant@Strawberry是的,我也这么想。我不确定目前还可以使用什么作为主键。@vanadium23我想这将返回一个表,其中一行的值为Python,而我想要的结果是两行的,Python和Flask。有什么想法吗?@Angularnoob我猜问题出在哪里,将查询重写为
从标记同义词中选择TargetTagName,其中SourceTagName IN('Py','Flask')或TargetTagName IN('Py','Flask')
将返回Flask,PythonI在Workbench中对此进行了测试,我认为这是理想的。我现在将在Node中尝试此功能,然后再与您联系。谢谢你,亚伦@草莓:如果没有第一个选择,您将无法为输入
Python
获取
Python
。查询的结果是系统直接或通过别名知道的一组标记。如果只是想将别名转换为名称,可以使用第二个查询。@AaronDigulla第一个输入是“Py”。您仍然无法获得“Flask”,因此应用程序必须对丢失的结果进行一些后处理。我不认为这比现有的解决方案有任何优势。@如果Flask已经在标签表中,您确实可以得到Flask。我很想听听你对我目前解决方案的看法@Angularnoob,但它不是:“第二个标签,Flask没有同义词,应该保持不变。”