> For the complete documentation index, see [llms.txt](https://vergil-lai.gitbook.io/manticoresearch-manual-zh/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://vergil-lai.gitbook.io/manticoresearch-manual-zh/creating_a_table/zi-ran-yu-yan-chu-li-nlp-he-fen-ci/wildcard_searching_settings.md).

# • 通配符搜索设置

通配符搜索是一种常见的文本搜索类型。在 Manticore 中，它是在字典级别执行的。默认情况下，普通表和实时表使用称为 [dict](/manticoresearch-manual-zh/creating_a_table/zi-ran-yu-yan-chu-li-nlp-he-fen-ci/low-level_tokenization.md#dict) 的字典类型。在此模式下，单词按原样存储，因此启用通配符不会影响表的大小。当执行通配符搜索时，系统会搜索字典以查找通配符单词的所有可能扩展。这种扩展在查询时可能会带来计算上的问题，特别是当扩展的单词提供许多扩展或具有巨大命中的情况下，尤其是在通配符被添加到单词的开头和结尾时。为避免此类问题，可以使用 [expansion\_limit](/manticoresearch-manual-zh/fu-wu-qi-she-zhi/searchd.md#expansion_limit)。

## min\_prefix\_len

```ini
min_prefix_len = length
```

此设置确定要索引和搜索的最小单词前缀长度。默认值设置为 0，这意味着不允许前缀。

前缀允许通过 `wordstart*` 通配符进行搜索。

例如，如果单词 "example" 的最小前缀长度设置为 3，则可以通过搜索 "exa"、"exam"、"examp"、"exampl" 以及完整单词来找到它。

请注意，对于 [dict](/manticoresearch-manual-zh/creating_a_table/zi-ran-yu-yan-chu-li-nlp-he-fen-ci/low-level_tokenization.md#dict)=crc，min\_prefix\_len 会影响全文索引的大小，因为每个单词扩展都会额外存储。

Manticore 可以将精确单词匹配与前缀匹配区分开，并在满足以下条件时对前者进行更高的排名：

* [dict](/manticoresearch-manual-zh/creating_a_table/zi-ran-yu-yan-chu-li-nlp-he-fen-ci/low-level_tokenization.md#dict)=keywords（默认开启）
* [index\_exact\_words](/manticoresearch-manual-zh/creating_a_table/zi-ran-yu-yan-chu-li-nlp-he-fen-ci/morphology.md#index_exact_words)=1（默认关闭）
* [expand\_keywords](/manticoresearch-manual-zh/5-sou-suo/options.md#expand_keywords)=1（同样默认关闭）

请注意，如果 [dict](/manticoresearch-manual-zh/creating_a_table/zi-ran-yu-yan-chu-li-nlp-he-fen-ci/low-level_tokenization.md#dict)=crc 模式或上述任何选项被禁用，则无法区分前缀和完整单词，且精确单词匹配无法获得更高的排名。

当 [最小中缀长度](#min_infix_len) 设置为正数时，最小前缀长度始终被视为 1。

**SQL:**

```sql
CREATE TABLE products(title text, price float) min_prefix_len = '3'
```

```json
POST /cli -d "
CREATE TABLE products(title text, price float) min_prefix_len = '3'"
```

```php
$index = new \Manticoresearch\Index($client);
$index->setName('products');
$index->create([
            'title'=>['type'=>'text'],
            'price'=>['type'=>'float']
        ],[
            'min_prefix_len' => '3'
        ]);
```

**Python:**

```python
utilsApi.sql('CREATE TABLE products(title text, price float) min_prefix_len = \'3\'')
```

**Javascript:**

```javascript
res = await utilsApi.sql('CREATE TABLE products(title text, price float) min_prefix_len = \'3\'');
```

**Java:**

```java
utilsApi.sql("CREATE TABLE products(title text, price float) min_prefix_len = '3'");
```

**C#:**

```clike
utilsApi.Sql("CREATE TABLE products(title text, price float) min_prefix_len = '3'");
```

```ini
table products {
  min_prefix_len = 3

  type = rt
  path = tbl
  rt_field = title
  rt_attr_uint = price
}
```

## min\_infix\_len

```ini
min_infix_len = length
```

min\_infix\_len 设置确定了要索引和搜索的中缀前缀的最小长度。它是可选的，默认值为 0，这意味着不允许中缀。允许的最小非零值为 2。

启用后，中缀允许使用术语模式进行通配符搜索，例如 `start*`、`*end`、`*middle*` 等。它还允许禁用过短的通配符，如果它们的搜索成本过高。

如果满足以下条件，Manticore 可以将精确单词匹配与中缀匹配区分开，并对前者进行更高的排名：

* [dict](/manticoresearch-manual-zh/creating_a_table/zi-ran-yu-yan-chu-li-nlp-he-fen-ci/low-level_tokenization.md#dict)=keywords（默认开启）
* [index\_exact\_words](/manticoresearch-manual-zh/creating_a_table/zi-ran-yu-yan-chu-li-nlp-he-fen-ci/low-level_tokenization.md#dict)=1（默认关闭）
* [expand\_keywords](/manticoresearch-manual-zh/5-sou-suo/options.md#expand_keywords)=1（同样默认关闭）

请注意，如果 [dict](/manticoresearch-manual-zh/creating_a_table/zi-ran-yu-yan-chu-li-nlp-he-fen-ci/low-level_tokenization.md#dict)=crc 模式或上述任何选项被禁用，则无法区分中缀和完整单词，因此精确单词匹配无法获得更高的排名。

中缀通配符搜索查询的时间可能会有很大差异，这取决于子字符串实际扩展为多少关键字。像 `*in*` 或 `*ti*` 这样的短而常见的音节可能会扩展为过多的关键字，而这些关键字都需要被匹配和处理。因此，为了普遍启用子字符串搜索，您应该将 min\_infix\_len 设置为 2。为了限制过短通配符搜索的影响，您可以将其设置得更高。

中缀必须至少为 2 个字符长，并且出于性能原因，不允许使用像 `*a*` 这样的通配符。

当 min\_infix\_len 设置为正数时， [最小前缀长度](#min_prefix_len) 被视为 1。对于 [dict](/manticoresearch-manual-zh/creating_a_table/zi-ran-yu-yan-chu-li-nlp-he-fen-ci/low-level_tokenization.md#dict) 来说，前缀和中缀不能同时启用。对于 [dict](/manticoresearch-manual-zh/creating_a_table/zi-ran-yu-yan-chu-li-nlp-he-fen-ci/low-level_tokenization.md#dict) 和其他字段，如果通过 [prefix\_fields](#prefix_fields) 声明了前缀，则禁止在两个列表中声明同一字段。

如果 dict=keywords，除了通配符 `*`，还可以使用两个其他通配符字符：

* `?` 可以匹配任何（一个）字符： `t?st` 将匹配 `test`，但不匹配 `teast`
* `%` 可以匹配零个或一个字符： `tes%` 将匹配 `tes` 或 `test`，但不匹配 `testing`

**SQL:**

```sql
CREATE TABLE products(title text, price float) min_infix_len = '3'
```

```json
POST /cli -d "
CREATE TABLE products(title text, price float) min_infix_len = '3'"
```

```php
$index = new \Manticoresearch\Index($client);
$index->setName('products');
$index->create([
            'title'=>['type'=>'text'],
            'price'=>['type'=>'float']
        ],[
            'min_infix_len' => '3'
        ]);
```

**Python:**

```python
utilsApi.sql('CREATE TABLE products(title text, price float) min_infix_len = \'3\'')
```

**Javascript:**

```javascript
res = await utilsApi.sql('CREATE TABLE products(title text, price float) min_infix_len = \'3\'');
```

**Java:**

```java
utilsApi.sql("CREATE TABLE products(title text, price float) min_infix_len = '3'");
```

**C#:**

```clike
utilsApi.Sql("CREATE TABLE products(title text, price float) min_infix_len = '3'");
```

```ini
table products {
  min_infix_len = 3

  type = rt
  path = tbl
  rt_field = title
  rt_attr_uint = price
}
```

## prefix\_fields

```ini
prefix_fields = field1[, field2, ...]
```

`prefix_fields` 设置用于在 [dict=crc](/manticoresearch-manual-zh/creating_a_table/zi-ran-yu-yan-chu-li-nlp-he-fen-ci/low-level_tokenization.md#dict) 模式下将前缀索引限制为特定的全文字段。默认情况下，所有字段都在前缀模式下索引，但由于前缀索引会影响索引和搜索性能，可能希望将其限制在某些特定字段上。

要将前缀索引限制为特定字段，请使用 `prefix_fields` 设置，后跟以逗号分隔的字段名称列表。如果未设置 `prefix_fields`，则所有字段都将在前缀模式下索引。

**CONFIG:**

```ini
table products {
  prefix_fields = title, name
  min_prefix_len = 3
  dict = crc
```

## infix\_fields

```ini
infix_fields = field1[, field2, ...]
```

`infix_fields` 设置允许你指定一个全文字段列表，以将中缀索引限制在这些字段中。该设置仅适用于 [dict=crc](/manticoresearch-manual-zh/creating_a_table/zi-ran-yu-yan-chu-li-nlp-he-fen-ci/low-level_tokenization.md#dict) 模式，且为可选项，默认情况下，所有字段都在中缀模式下索引。

此设置类似于 [prefix\_fields](/manticoresearch-manual-zh/creating_a_table/zi-ran-yu-yan-chu-li-nlp-he-fen-ci/low-level_tokenization.md#dict)，但它允许将中缀索引限制在特定字段上。

**CONFIG:**

```ini
table products {
  infix_fields = title, name
  min_infix_len = 3
  dict = crc
```

## max\_substring\_len

```ini
max_substring_len = length
```

`max_substring_len` 指令设置用于前缀或中缀搜索的最大子字符串长度。该设置为可选项，默认值为 0（即索引所有可能的子字符串）。该指令仅适用于 [dict](/manticoresearch-manual-zh/creating_a_table/zi-ran-yu-yan-chu-li-nlp-he-fen-ci/low-level_tokenization.md#dict) 模式。

在 [dict](/manticoresearch-manual-zh/creating_a_table/zi-ran-yu-yan-chu-li-nlp-he-fen-ci/low-level_tokenization.md#dict) 模式中，默认情况下，子字符串索引将 **所有** 可能的子字符串作为独立关键词进行索引，这可能会导致全文索引过大。因此，`max_substring_len` 指令允许跳过可能永远不会被搜索的过长子字符串。

例如，一个包含 10,000 篇博客文章的测试表根据设置的不同会占用不同的磁盘空间：

* 6.4 MB 基线（没有子字符串）
* 24.3 MB (3.8倍) 当 `min_prefix_len = 3`
* 22.2 MB (3.5倍) 当 `min_prefix_len = 3, max_substring_len = 8`
* 19.3 MB (3.0倍) 当 `min_prefix_len = 3, max_substring_len = 6`
* 94.3 MB (14.7倍) 当 `min_infix_len = 3`
* 84.6 MB (13.2倍) 当 `min_infix_len = 3, max_substring_len = 8`
* 70.7 MB (11.0倍) 当 `min_infix_len = 3, max_substring_len = 6`

因此，限制最大子字符串长度可以节省 10-15% 的表空间。

在 `dict=keywords` 模式下，子字符串长度对性能没有影响，因此该指令不适用并且在此模式下被禁止使用。不过，如果需要，仍然可以在应用代码中限制搜索的子字符串长度。

**CONFIG:**

```ini
table products {
  max_substring_len = 12
  min_infix_len = 3
  dict = crc
```

## expand\_keywords

```ini
expand_keywords = {0|1|exact|star}
```

该设置用于扩展关键词的确切形式和/或在关键词周围添加星号。支持的值有：

* 1 - 扩展为确切形式和带星号的形式。例如，`running` 会被扩展为 `(running | *running* | =running)`
* \`\`exact `- 仅扩展关键词的确切形式。例如，`running`会被扩展为`(running | =running)\`
* `star` - 通过在关键词周围添加 `*` 扩展关键词。例如，`running` 会被扩展为 `(running | *running*)`

当启用 `expand_keywords` 功能时，对表执行的查询会进行内部扩展：如果构建表时启用了前缀或中缀索引，系统会将每个关键词内部替换为该关键词本身及相应的前缀或中缀（带星号的关键词）的析取形式。如果表在构建时启用了词干提取和 [index\_exact\_words](/manticoresearch-manual-zh/creating_a_table/zi-ran-yu-yan-chu-li-nlp-he-fen-ci/morphology.md#index_exact_words)，则还会添加关键词的确切形式。

**SQL:**

```sql
CREATE TABLE products(title text, price float) expand_keywords = '1'
```

```JSON
POST /cli -d "
CREATE TABLE products(title text, price float) expand_keywords = '1'"
```

```php
$index = new \Manticoresearch\Index($client);
$index->setName('products');
$index->create([
            'title'=>['type'=>'text'],
            'price'=>['type'=>'float']
        ],[
            'expand_keywords' => '1'
        ]);
```

**Python:**

```python
utilsApi.sql('CREATE TABLE products(title text, price float) expand_keywords = \'1\'')
```

**Javascript:**

```javascript
res = await utilsApi.sql('CREATE TABLE products(title text, price float) expand_keywords = \'1\'');
```

**Java:**

```java
utilsApi.sql("CREATE TABLE products(title text, price float) expand_keywords = '1'");
```

**C#:**

```clike
utilsApi.Sql("CREATE TABLE products(title text, price float) expand_keywords = '1'");
```

```ini
table products {
  expand_keywords = 1

  type = rt
  path = tbl
  rt_field = title
  rt_attr_uint = price
}
```

扩展查询自然会增加查询完成的时间，但可能会提高搜索质量，因为匹配确切形式的文档通常会比匹配词干或中缀的文档排名更高。

**注意，现有的查询语法无法模拟这种扩展**，因为内部扩展是在关键词级别上进行的，且扩展关键词包括短语或配额操作符内的关键词（这是查询语法无法实现的）。下列示例展示了 `expand_keywords` 如何影响搜索结果权重，以及如何通过 "runs" 查找到 "runsy"，而不需要添加星号：

**expand\_keywords is enabled**

```sql
mysql> create table t(f text) min_infix_len='2' expand_keywords='1' morphology='stem_en';
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql> insert into t values(1,'running'),(2,'runs'),(3,'runsy');
Query OK, 3 rows affected (0.00 sec)

mysql> select *, weight() from t where match('runs');
+------+---------+----------+
| id   | f       | weight() |
+------+---------+----------+
|    2 | runs    |     1560 |
|    1 | running |     1500 |
|    3 | runsy   |     1500 |
+------+---------+----------+
3 rows in set (0.01 sec)

mysql> drop table t;
Query OK, 0 rows affected (0.01 sec)

mysql> create table t(f text) min_infix_len='2' expand_keywords='exact' morphology='stem_en';
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql> insert into t values(1,'running'),(2,'runs'),(3,'runsy');
Query OK, 3 rows affected (0.00 sec)

mysql> select *, weight() from t where match('running');
+------+---------+----------+
| id   | f       | weight() |
+------+---------+----------+
|    1 | running |     1590 |
|    2 | runs    |     1500 |
+------+---------+----------+
2 rows in set (0.00 sec)
```

**expand\_keywords is disabled**

```sql
mysql> create table t(f text) min_infix_len='2' morphology='stem_en';
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql> insert into t values(1,'running'),(2,'runs'),(3,'runsy');
Query OK, 3 rows affected (0.00 sec)

mysql> select *, weight() from t where match('runs');
+------+---------+----------+
| id   | f       | weight() |
+------+---------+----------+
|    1 | running |     1500 |
|    2 | runs    |     1500 |
+------+---------+----------+
2 rows in set (0.00 sec)

mysql> drop table t;
Query OK, 0 rows affected (0.01 sec)

mysql> create table t(f text) min_infix_len='2' morphology='stem_en';
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql> insert into t values(1,'running'),(2,'runs'),(3,'runsy');
Query OK, 3 rows affected (0.00 sec)

mysql> select *, weight() from t where match('running');
+------+---------+----------+
| id   | f       | weight() |
+------+---------+----------+
|    1 | running |     1500 |
|    2 | runs    |     1500 |
+------+---------+----------+
2 rows in set (0.00 sec)
```

该指令不会对 [indexer](/manticoresearch-manual-zh/data_creation_and_modification/cong-wai-bu-cun-chu-tian-jia-shu-ju/plain_tables_creation.md#Indexer-tool) 产生任何影响，它仅对 [searchd](/manticoresearch-manual-zh/starting_the_server/manually.md) 有效。

## expansion\_limit

```ini
expansion_limit = number
```

单个通配符扩展的最大关键词数量。详情请参见 [这里](/manticoresearch-manual-zh/fu-wu-qi-she-zhi/searchd.md#expansion_limit)。
