About me

Step two: REPLACE, UPDATE, wordforms
在我写我的 第一篇文章 时,我的宠物商店的朋友联系了我。他们想为他们的商店使用数据库,由于他们的销售人员仍然在系绳和项圈之间感到困惑,我想要实施数据库的附加功能。
这篇文章是 上一篇文章 的延续,并且基于它。
与大多数数据库不同,Manticore使用一种先进的模型来识别它所存储的文本。该文本处理系统基于自然语言处理(NLP)解决方案。
这里稍微描述一下技术以便于一般理解。在文本识别中,NLP旨在识别我们交流中的“自然”语言。乍一看,文本识别似乎没有什么复杂之处,从技术上讲,随着使用机器学习算法的文本处理解决方案的出现,它变得如此简单。在我们的案例中,我们不会深入研究,而是会使用Manticore Search中已经内置的现成文本处理解决方案。该系统使用分词(将文本分割)成小的独立部分:按句子和按单词,这使得能够在数据库中快速找到所需的单词、短语和段落。 (有关数据分词的更多信息,请查看此 链接。 )
以下是关于Manticore使用的技术的一些介绍:
- 词干提取是将单词还原为其根形式的过程。例如,“walking”、“walks”和“walked”都是“walk”的词干。
- 词形还原是将不同形式的单词转换为其基本形式(称为词元)的过程。例如,“eat”这个词可以以“eating”、“eats”和“ate”的形式出现。这些变体的词元是“eat”,这是它的基本词典形式。
- 为了提高高级搜索的准确性和质量,使用了其他几种解决方案:词形、例外和停用词。
词形还原器和词干提取器执行一项共同职能,即将单词标准化为相同的形式,但方式不同,每种方式都有其优缺点。
此外,包含选择语言的常用词列表(如冠词、连词和感叹词)的停用词文件有助于加快处理过程。基本上,所有这些小词让我们的语言听起来悦耳,但对于计算机来说并没有太多实际意义。
如果标准功能集不足以让搜索引擎舒适运行,例如,当数据库包含专业术语或地方俚语,并且单词之间存在额外语义意义的逻辑关系时,可以使用 附加词形文件。数据库管理员可以在文件中添加单词之间的链接,这些单词在定义规则上有所不同,但在上下文中对该数据库是相似的。例如,系绳和马具。在不同上下文中,这两个词可能有相同的含义或完全不同。
Using a word forms file in a table
New tables
宠物商店的员工提到他们的销售人员对系绳和马具不太了解。他们建议在询问系绳时,还应该考虑询问马具,反之亦然。
由于系绳和马具属于同一产品类别,并且数据库中没有特定字段来指示它们的组,因此使用词形文件可能会带来好处。该文件可以帮助在搜索“leash”时添加相关单词。例如,通过将“harness”或“flexi”之类的单词添加到词形字典中,搜索“leash”时也会得到“harness”和“flexi”的结果。
让我们看看这家宠物商店提供的产品:
Title | Description | Price | Availability |
---|---|---|---|
Canvas leash, green, up to 50 kg, 5m | 结实的帆布狗绳,长度为5米,适合大型犬种 | 5.00€ | yes |
Elastic leash, pink, up to 10 kg, 3m | 适合优雅女士及其四条腿的伴侣的漂亮绳子 | 12.00€ | no |
粉色背带,最大10千克 | 用于被释放到街道上并误称为狗的房间护卫 | 8.00€ | 是 |
flexi可伸缩狗绳,10千克,5米 | 适用于最大10千克的狗。长度为5米,考虑到主人伸出手臂的长度 | 7.50€ | 是 |
狗粮,1千克 | 适合您宠物的干粮 | 4.30€ | 否 |
猫粮,1千克 | 如果您的猫大喊并要求食物! | 2.80€ | 是 |
猫用跳蚤项圈 | 猫不应该成为跳蚤的载体。 | 23.20€ | 是 |
适用于最大10千克狗的跳蚤药水 | 对您护卫的皮肤上的不速之客有效的药水 | 14.30€ | 是 |
我们将把 Title
字段设置为一个字符串,将 Description
用于全文搜索,将 Price
设置为浮点数,将 Availability
设置为布尔值。
为了建立“绳子”、“背带”和“flexi”之间的逻辑词连接,我们将它们放在 /tmp/wordforms/
中的文件中,并确保所有用户都可以访问。
mkdir /tmp/wordforms
cd /tmp/wordforms
mcedit wf_pet_products.txt
MC中的内置编辑器称为 mcedit
。要执行该命令,请输入 mcedit <文件名>
。
让我们将我们的词形添加到那里:
flexi > leash
harness > leash
如果您做得正确,您会在终端中看到类似以下内容:
F2 保存
Enter 确认
F10 退出
现在我们有了一个将用于新表的单词文件。记住或记录保存位置:
/tmp/wordforms/wf_pet_products.txt
现在,为了对数据库进行更多更改,我们必须连接到它并设置一个包含我们列的表。然后,我们需要链接一个词干分析器和我们之前制作的词形文件:
mysql -h0 -P9306
CREATE TABLE products (name STRING, info TEXT, price FLOAT, avl BOOL) morphology = 'stem_en' wordforms='/tmp/wordforms/wf_pet_products.txt';
现在让我们检查表中创建了哪些字段:
DESC products;
我们指定的所有字段都存在,但出现了一个额外字段 - id
。此字段旨在使Manticore唯一标识数据库中的文档,因此在表初始化时自动创建,而不管规格。信息字段具有 indexed stored
属性,表示它参与全文搜索过程。值得注意的是,字段的顺序与创建表时指定的顺序不同。因此,在填充表时,必须考虑到这一点,特别是在不在命令中指定字段顺序的情况下更新整行。例如,在即将讨论的 REPLACE
命令中。
接下来,我们应该验证表的总体参数,例如词形文件和之前连接的词干分析器。当创建表时,如果词形文件名存在错误,系统将忽略它,而不会产生任何错误或警告。
SHOW TABLE products SETTINGS;
在上面,您可能会注意到,尽管我们指定了 /tmp/wordforms/
中的文件路径,Manticore将其保存在 /var/lib/manticore/products/
中。这表明Manticore已经将文件的副本附加到创建的表中。该文件现在是固定的,用于对该表进行索引。按需替换词形文件不可用,设计上是因为这需要对整个表进行重新索引,如果您有一个非常大的表,这可能不是理想的。我们稍后将讨论如何安全且可预测地替换这样的文件。
这完成了表的设置,下一步是输入所需的数据。数据输入与任何SQL数据库的方式相似。
INSERT INTO products (name, price, avl) VALUES ('帆布绳,绿色,最大50千克,5米', 5.0, 1);
INSERT INTO products (name, price, avl, info) VALUES ('弹性绳,粉色,最大10千克,3米', 12.00, 0, '适合洗练女士及其四脚伴侣的美丽绳子');
INSERT INTO products (name, price, avl, info) VALUES ('粉色背带,最大10千克', 8.00, 1, '用于被释放到街道上并误称为狗的房间护卫');
INSERT INTO products (name, price, avl, info) VALUES ('flexi可伸缩狗绳,10千克,5米', 7.50, 1, '适用于最大10千克的狗。长度为5米,考虑到主人伸出手臂的长度');
INSERT INTO products (name, price, avl, info) VALUES ('狗粮,1千克', 4.30, 0, '适合您宠物的干粮');
INSERT INTO products (name, price, avl, info) VALUES ('猫粮,1千克', 2.80, 1, '如果您的猫大喊并要求食物!');
INSERT INTO products (name, price, avl, info) VALUES ('猫用跳蚤项圈 , 1千克', 23.20, 1, '猫不应该成为跳蚤的载体。');
INSERT INTO products (name, price, avl, info) VALUES ('适用于最大10千克狗的跳蚤药水', 14.30, 1, '对您护卫的皮肤上的不速之客有效的药水');
请注意使用撇号;文本中有使用撇号的缩写,重要的是用 \
将它们与其余文本隔开: 'Isn\'t it'
。Manticore 不支持双引号 作为字符串,这在避免转义单撇号时会很有用。
在上面的第一个请求中,故意省略了 info
字段,以演示如何更新全文字段。值得注意的是,更新文本字段和属性字段的处理方式不同。全文字段通过 REPLACE
命令进行更新,这会触发新值的重新索引,而对于其他字段,UPDATE
命令就足够了。这是因为属性字段不参与全文搜索索引过程。
现在,让我们使用 REPLACE
命令向现有记录的某些字段添加数据。要使用此命令,您需要我们要更改或添加信息的行的唯一 ID。首先,我们将使用 SELECT * FROM products
获取所需的数据;
SELECT * FROM products WHERE name = 'Canvas leash, green, up to 50 kg, 5m';
确保记住字段的位置。我们稍后需要这些信息。此外,我们需要字段中的所有当前数据,因为替换命令将用这些数据更新整个文件。如果我们不指定所有数据,没有指定的字段将被重置。根据字段位置填写 REPLACE
命令。
REPLACE INTO products VALUES (<id>, <info>, <avl>, <price>, <name>);
在开发版本中,当您阅读此内容时,可能已经发布,可以更换特定字段。有关更多详细信息,请参阅 documentation 。
REPLACE INTO products VALUES (8217224102746783745, 'Sturdy canvas dog leash for 5 meters, suitable for large dog breeds', 1, 5.0, 'Canvas leash, green, up to 50 kg, 5m');
小心这里的代码,如果您只是从文章中复制命令,您表中的 ID 字段值将会不同!如果 Manticore 找不到具有指定 ID 的记录,将创建一条新记录。
要更新 “attributes” 字段,您可以使用 UPDATE
命令。顺便提一下,输入数据时,绿色狗绳的价格略微下降:
update products set price = 4.6 where id = 8217224102746783745;
让我们检查结果:
SELECT * FROM products WHERE id = 8217224102746783745;
我们已经达到了预期的结果,现在让我们尝试搜索,因为我们正在为商店创建产品数据库,以便于卖家找到产品。用于在表中搜索的命令是 select * from <table> where match('<query>')
.
SELECT * FROM products WHERE match('harness');
SELECT * FROM products WHERE match ('leash');
很好,现在数据库正在为我们的查询提供答案,使用我们通过单词表文件创建的连接。但输出中似乎缺少了什么?室内护卫的粉色狗绳的条目在哪里?
在 info
字段中,没有类似于绳子或项圈的字样,它们只出现在 name
字段中,所以该条目没有出现在输出中。让我们修复一下:
SELECT * FROM products WHERE name = 'Pink harness, up to 10 kg';
REPLACE INTO products VALUES (8217224102746783747,'Harness for room guards released into the street and mistakenly called a dog', 1, 8.0, 'Pink harness, up to 10 kg');
让我们检查发生了什么:
SELECT * FROM products WHERE match('harness');
现在这个记录已包含在输出中。如您所见,只有与索引字段相关的信息才参与搜索;其余字段是索引字段的属性。
扩展表
在宠物店,他们引进了新货物,现在他们也有水族设备。为了确保我们可以轻松找到与水族设备相关的单词,例如泵或驱动器,我们需要向我们的单词列表添加条目。
Title | Description | Price | Availability |
---|---|---|---|
水族箱用泵. | 一种带内置过滤器的水族箱泵。容量 150 l/h | 32.00€ | 是 |
水族箱用自动过滤器 | 带过滤器的一次性驱动器,容量 100 l/h。 | 28.00€ | 是 |
鱼网 | 非创伤性水族箱鱼网 | 3.00€ | 是 |
让我们将它们添加到数据库中:
INSERT INTO products (name, info, price, avl) VALUES ('The pump for the aquarium.', 'Pump with built-in aquarium filter. Capacity 150 l/h', 32, 1), ('Automatic filter for aquarium', 'Disposable drive with filter, capacity 100 l/h', 28.00, 1), ('Fish net', 'Atraumatic aquarium fish net', 3, 1);
在这里,我们使用了一个命令进行填充,逗号分隔的新行枚举,这样您可以通过一个命令添加大量文档。
让我们检查搜索:
SELECT * FROM products WHERE match ('pump');
SELECT * FROM products WHERE match ('filter');
好吧,这意味着一些东西。然而,驱动器不被视为泵。这应该添加到我们使用的单词列表中……
让我们来做。
哦,这里有个小问题。这可不是那么简单……
当我们为文本创建搜索系统时,我们将所有单词放入一个表中,并将它们转换为标记以提高搜索效率。这些标记后续不再更新,以加快搜索过程。然而,在某些情况下,我们需要更新词形文件,并相应地修改标记。让我们更新词形文件中的单词列表,并将产品名称包含到搜索索引的 name
字段中。
要更新表中的词形文件,我按照以下步骤操作:
- 使用
mysqldump
创建此表的转储。 - 更新词形文件。
- 删除旧表。
- 创建一个包含形态学部分更新词形的新表。
- 从转储文件中填充新表。
创建转储文件(备份):
在任何不清楚的情况下,备份表以防止数据丢失。(这条规则可以贴在墙上作为提醒)。
这也帮助我们实现目标。
要完成这项工作,我们需要断开 SQL 连接并使用 mysqldump
工具。
exit;
mkdir /tmp/manticore_dumps
cd /tmp/manticore_dumps
mysqldump -h0 -P9306 -tc --compact manticore products > products.sql
我使用的标志是:
-t
- 从转储中排除create table
语句。-c
- 在INSERT
命令中指定列名。--compact
- 以紧凑格式执行数据库转储,省略检查表可用性、删除表、创建新表、为创建的表设置配置等部署操作。在我们的情况下,这些过程是不必要的,因为我们需要在表中注册一个新的词典文件。manticore
- 是mysqldump
的数据库名称,在使用 Manticore 的mysqldump
时必须始终为manticore
。products
- 我们要创建转储的表名。products.sql
- 转储将上传到的文件名。文件的默认目录是启动mysqldump
的目录。我建议指定/tmp/
以确保后续示例成功。或者,您可以输入完整路径:/tmp/manticore_dumps/products.sql
。
如果看到:"– Warning: column statistics not supported by the server.“不用担心,这是使用此 mysql 工具与 Manticore 时的正常情况。
很好,我们有了第一个转储!
更新词形文件:
你是不是忘记了词形文件的位置?
cd /tmp/wordforms
如果你正在使用 MC 但由于某些原因看不到文件列,请尝试使用 Ctrl + O 组合键。如果没有变化,可能 MC 没有运行。
接下来,使用箭头键导航。当你需要选择文件时,按 F4 打开选定的文件。
添加新字符串:“drive > pump”
保存并关闭。F2,Enter,F10。
文件已更新。
删除表并创建新表:
在删除表之前,请确保已有转储,并且转储确实包含我们的数据。
cd /tmp/manticore_dumps/
选择转储文件并按 F3 按钮查看。
您也可以在控制台使用命令 cat /tmp/manticore_dumps/products.sql
查看。
你应该看到类似这样的内容:
好的,让我们继续删除旧表并创建新表:
mysql -h0 -P9306
DROP TABLE products;
CREATE TABLE products (name TEXT, info TEXT, price FLOAT, avl BOOL) morphology = 'stem_en' wordforms='/tmp/wordforms/wf_pet_products.txt';
我们删除了这个表,然后立即重新创建(使用与之前相同的命令,但稍作更改:现在 name 字段也是文本),现在我们必须向其中添加信息。
exit;
从转储重新填充:
mysql -h0 -P9306 < /tmp/manticore_dumps/products.sql
mysql -h0 -P9306
我们填充完了。让我们检查最终结果:
SELECT * FROM products WHERE match ('pump');
很棒,一切正常!
在更新表时,特别是大表,会有一个时期,旧表已被删除但新表尚未创建。在这个间隔期间,系统可能对请求以错误响应。为确保 Manticore 平稳运行,有几个系统可以帮助避免丢失用户请求。我将在后面学习如何实现。
在本文中,我展示了如何为宠物店库存设置和使用 Manticore Search。通过使用词形和形态学,Manticore 帮助通过链接相关的产品名称和类型来改善搜索结果。我介绍了如何添加新项目、更新现有项目,并在更改词形文件等重大更新期间确保数据一致性。这有助于初学者理解和应用 Manticore Search 的功能,使数据搜索更加高效。未来的文章将探索更多功能,让我们一起继续尝试 Manticore 以增强您的项目。
今天就到这里。Mike,下线。