blog-post

Mike learning: REPLACE, UPDATE, wordforms

About me

Mike

你好,我又是Mike。

我最近开始在Manticore担任开发者倡导者。我并不是一个完全与IT无关的人,但我正在赶上现代技术。在这个博客中,我将分享我对Manticore的经验和所学。我的计划是以日记的形式记录我的旅程,解释Manticore是什么以及如何使用它。让我们一起发现事物是如何相互作用的,识别问题,并与开发者实时互动。

这是我的第二篇博客文章。如果您有兴趣与我一起学习Manticore,我会通过以下方式保持您更新:

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”的结果。

让我们看看这家宠物商店提供的产品:

TitleDescriptionPriceAvailability
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

如果您做得正确,您会在终端中看到类似以下内容:
Terminal view
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;

DESC results

我们指定的所有字段都存在,但出现了一个额外字段 - id。此字段旨在使Manticore唯一标识数据库中的文档,因此在表初始化时自动创建,而不管规格。信息字段具有 indexed stored 属性,表示它参与全文搜索过程。值得注意的是,字段的顺序与创建表时指定的顺序不同。因此,在填充表时,必须考虑到这一点,特别是在不在命令中指定字段顺序的情况下更新整行。例如,在即将讨论的 REPLACE 命令中。

接下来,我们应该验证表的总体参数,例如词形文件和之前连接的词干分析器。当创建表时,如果词形文件名存在错误,系统将忽略它,而不会产生任何错误或警告。

SHOW TABLE products SETTINGS;

Show table products settings result

在上面,您可能会注意到,尽管我们指定了 /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';

Result of select * from products where name&hellip;

确保记住字段的位置。我们稍后需要这些信息。此外,我们需要字段中的所有当前数据,因为替换命令将用这些数据更新整个文件。如果我们不指定所有数据,没有指定的字段将被重置。根据字段位置填写 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;

Printscreen of query &lsquo;where id&rsquo; result

我们已经达到了预期的结果,现在让我们尝试搜索,因为我们正在为商店创建产品数据库,以便于卖家找到产品。用于在表中搜索的命令是 select * from <table> where match('<query>').

SELECT * FROM products WHERE match('harness');
SELECT * FROM products WHERE match ('leash');

Query result for &lsquo;roulette&rsquo;

很好,现在数据库正在为我们的查询提供答案,使用我们通过单词表文件创建的连接。但输出中似乎缺少了什么?室内护卫的粉色狗绳的条目在哪里?
info 字段中,没有类似于绳子或项圈的字样,它们只出现在 name 字段中,所以该条目没有出现在输出中。让我们修复一下:

SELECT * FROM products WHERE name = 'Pink harness, up to 10 kg';

Query result from &ldquo;pink harness&rdquo;

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');

Query result &lsquo;harness&rsquo; after table update
现在这个记录已包含在输出中。如您所见,只有与索引字段相关的信息才参与搜索;其余字段是索引字段的属性。

扩展表

在宠物店,他们引进了新货物,现在他们也有水族设备。为了确保我们可以轻松找到与水族设备相关的单词,例如泵或驱动器,我们需要向我们的单词列表添加条目。

TitleDescriptionPriceAvailability
水族箱用泵.一种带内置过滤器的水族箱泵。容量 150 l/h32.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');

Query result &lsquo;pump&rsquo; and &lsquo;filter

好吧,这意味着一些东西。然而,驱动器不被视为泵。这应该添加到我们使用的单词列表中……
让我们来做。
哦,这里有个小问题。这可不是那么简单……
当我们为文本创建搜索系统时,我们将所有单词放入一个表中,并将它们转换为标记以提高搜索效率。这些标记后续不再更新,以加快搜索过程。然而,在某些情况下,我们需要更新词形文件,并相应地修改标记。让我们更新词形文件中的单词列表,并将产品名称包含到搜索索引的 name 字段中。

要更新表中的词形文件,我按照以下步骤操作:

  1. 使用 mysqldump 创建此表的转储。
  2. 更新词形文件。
  3. 删除旧表。
  4. 创建一个包含形态学部分更新词形的新表。
  5. 从转储文件中填充新表。
创建转储文件(备份):

在任何不清楚的情况下,备份表以防止数据丢失。(这条规则可以贴在墙上作为提醒)。
这也帮助我们实现目标。
要完成这项工作,我们需要断开 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”
添加了字符串的词形文件
保存并关闭。F2EnterF10
文件已更新。

删除表并创建新表:

在删除表之前,请确保已有转储,并且转储确实包含我们的数据。

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');

很棒,一切正常!
更新词形后的结果 &ldquo;select * &hellip; mathc(&lsquo;pump&rsquo;)&rdquo;

在更新表时,特别是大表,会有一个时期,旧表已被删除但新表尚未创建。在这个间隔期间,系统可能对请求以错误响应。为确保 Manticore 平稳运行,有几个系统可以帮助避免丢失用户请求。我将在后面学习如何实现。

在本文中,我展示了如何为宠物店库存设置和使用 Manticore Search。通过使用词形和形态学,Manticore 帮助通过链接相关的产品名称和类型来改善搜索结果。我介绍了如何添加新项目、更新现有项目,并在更改词形文件等重大更新期间确保数据一致性。这有助于初学者理解和应用 Manticore Search 的功能,使数据搜索更加高效。未来的文章将探索更多功能,让我们一起继续尝试 Manticore 以增强您的项目。

今天就到这里。Mike,下线。

结束照片

安装Manticore Search

安装Manticore Search