Python API接口

Lance 是一种专为高效多模态数据处理而设计的列式存储格式。

Lance数据集

Lance的核心是LanceDataset类。用户可以通过使用 lance.dataset()来打开数据集。

lance.dataset(uri: str | Path, 版本: int | str | None = None, asof: ts_types | None = None, block_size: int | None = None, commit_lock: CommitLock | None = None, index_cache_size: int | None = None, storage_options: dict[str, str] | None = None, default_scan_options: dict[str, str] | None = None) LanceDataset

从指定地址打开Lance数据集。

Parameters:
uri : str

Lance数据集的地址。可以是本地文件路径/tmp/data.lance,也可以是云对象存储URI,例如s3://bucket/data.lance

version : optional, int | str

如果指定,则加载Lance数据集的特定版本。否则,加载最新版本。可以提供一个版本号(int)或标签(str)。

asof : optional, datetime or str

如果指定此参数,则查找在给定参数值当天或之前创建的最新版本。如果已指定版本号,则忽略此参数。

block_size : optional, int

块大小(以字节为单位)。为最小I/O请求的大小提供提示。

commit_lock : optional, lance.commit.CommitLock

自定义提交锁。仅当您的对象存储不支持原子提交时才需要。详情请参阅用户指南。

index_cache_size : optional, int

索引缓存大小。索引缓存是一个带有TTL的LRU缓存。该数值指定了 在主机内存中缓存的索引页数量,例如IVF分区数。默认值为256

粗略来说,对于一个包含n行的IVF_PQ分区,每个索引页的大小等于 pq编码(nd.array([n,pq], dtype=uint8)))和行ID(nd.array([n], dtype=uint64))的组合。 近似计算为n = 总行数 / IVF分区数量pq = PQ子向量数量

storage_options : optional, dict

针对特定存储连接的额外选项。这用于存储连接参数,如凭证、端点等。

default_scan_options : optional, dict

扫描数据集时使用的默认扫描选项。这接受与lance.LanceDataset.scanner()中描述的相同参数。这些参数将应用于任何扫描操作。

这对于为常见参数(如batch_size)提供默认值非常有用。

它还可用于创建包含元字段(如_rowid_rowaddr)的数据集视图。如果提供了default_scan_options,那么当设置了适当的扫描选项时,lance.LanceDataset.schema()返回的模式将包含这些字段。

基础输入输出

以下函数用于读取和写入Lance格式的数据。

LanceDataset.insert(数据: ReaderLike, *, mode='append', **kwargs)

将数据插入数据集。

Parameters:
data_obj : Reader-like

要写入的数据。可接受的类型包括: - Pandas DataFrame、Pyarrow Table、Dataset、Scanner 或 RecordBatchReader - Huggingface 数据集

mode : str, default 'append'

写入数据时使用的模式。可选选项有:

create - 创建新数据集(如果uri已存在则会报错)。 overwrite - 创建新的快照版本 append - 创建新版本,该版本是输入数据与最新版本的合并(如果uri不存在则会报错)

**kwargs : dict, optional

传递给write_dataset()的其他关键字参数。

LanceDataset.scanner(columns: list[str] | dict[str, str] | None = None, filter: 表达式 | str | None = None, limit: int | None = None, offset: int | None = None, nearest: dict | None = None, batch_size: int | None = None, batch_readahead: int | None = None, fragment_readahead: int | None = None, scan_in_order: bool | None = None, 片段: Iterable[LanceFragment] | None = None, full_text_query: str | dict | FullTextQuery | None = None, *, prefilter: bool | None = None, with_row_id: bool | None = None, with_row_address: bool | None = None, use_stats: bool | None = None, fast_search: bool | None = None, io_buffer_size: int | None = None, late_materialization: bool | list[str] | None = None, use_scalar_index: bool | None = None, include_deleted_rows: bool | None = None, scan_stats_callback: Callable[[ScanStatistics], None] | None = None, strict_batch_size: bool | None = None) LanceScanner

返回一个支持各种下推操作的Scanner。

Parameters:
columns : list of str, or dict of str to str default None

要获取的列名列表。 或者列名到SQL表达式的字典。 如果为None或未指定,则获取所有列。

filter : pa.compute.Expression or str

表达式或字符串,必须是一个有效的SQL where子句。有关有效的SQL表达式,请参阅 Lance filter pushdown

limit : int, default None

最多获取这么多行。如果为None或未指定,则获取所有行。

offset : int, default None

从这一行开始获取。如果未指定则为0。

nearest : dict, default None

获取与K个最相似向量对应的行。示例:

{
    "column": <embedding col name>,
    "q": <query vector as pa.Float32Array>,
    "k": 10,
    "minimum_nprobes": 20,
    "maximum_nprobes": 50,
    "refine_factor": 1
}

batch_size : int, default None

返回批次的目标大小。在某些情况下,批次大小可能达到此值的两倍(但绝不会超过)。而在其他情况下,批次大小可能小于此值。

io_buffer_size : int, default None

IO缓冲区的大小。有关更多信息,请参阅ScannerBuilder.io_buffer_size

batch_readahead : int, optional

预读取的批次数量。

fragment_readahead : int, optional

预读取的片段数量。

scan_in_order : bool, default True

是否按顺序读取片段和批次。如果为false,吞吐量可能会更高,但批次将无序返回,内存使用可能会增加。

fragments : iterable of LanceFragment, default None

如果指定,则仅扫描这些片段。如果scan_in_order为True,那么片段将按照给定的顺序进行扫描。

prefilter : bool, default False

如果为True,则在运行向量查询之前应用过滤器。 这将生成更准确的结果,但查询成本可能更高。 通常在过滤器具有高选择性时效果良好。

如果为False,则在运行向量查询之后应用过滤器。 这样性能会更好,但如果最接近查询的行不匹配过滤器, 结果可能会少于请求的行数(或为空)。 通常在过滤器选择性不高时效果良好。

use_scalar_index : bool, default True

Lance会自动使用标量索引来优化查询。在某些极端情况下,这可能会使查询性能变差,此时可以通过该参数禁用标量索引。

late_materialization : bool or List[str], default None

允许自定义控制延迟物化。延迟物化会在过滤操作后通过take操作获取非查询列,这在结果较少或列数据量非常大时非常有用。

当结果较多或列数据非常窄时,早期物化可能更优。

如果设为True,则所有列都采用延迟物化; 如果设为False,则所有列都采用早期物化; 如果是字符串列表,则只有列表中的列会延迟物化。

默认采用启发式算法,假设过滤器会筛选出约0.1%的行。如果您的过滤器选择性更强(例如按id查找),可能需要设为True;如果过滤器选择性较弱(例如匹配20%的行),可能需要设为False。

full_text_query : str or dict, optional

要搜索的查询字符串,结果将按BM25算法排序。 例如"hello world"会匹配包含"hello"或"world"的文档。 或者使用包含以下键的字典:

  • columns: list[str]

    要搜索的列, 目前columns列表中仅支持单个列。

  • query: str

    要搜索的查询字符串。

如果为True,则搜索将仅在索引数据上执行,这样可以缩短搜索时间。

scan_stats_callback : Callable[[ScanStatistics], None], default None

一个回调函数,在扫描完成后将调用该函数并传入扫描统计信息。回调函数引发的错误将被记录但不会重新抛出。

include_deleted_rows : bool, default False

如果为True,则已被删除但仍存在于片段中的行将被返回。这些行的_rowid列将被设为null。所有其他列将反映磁盘上存储的值,可能不为null。

注意:如果是搜索操作或take操作(包括标量索引扫描),则无法返回已删除的行。

注意

目前,如果同时指定了filter和nearest,那么:

  1. nearest 会优先执行。

  2. 结果会在之后进行过滤。

为了调试近似最近邻(ANN)结果,您可以选择即使存在索引也不使用它,只需指定use_index=False。例如,以下代码将始终返回精确的KNN结果:

dataset.to_table(nearest={
    "column": "vector",
    "k": 10,
    "q": <query vector>,
    "use_index": False
}
LanceDataset.to_batches(columns: list[str] | dict[str, str] | None = None, filter: 表达式 | str | None = None, limit: int | None = None, offset: int | None = None, nearest: dict | None = None, batch_size: int | None = None, batch_readahead: int | None = None, fragment_readahead: int | None = None, scan_in_order: bool | None = None, *, prefilter: bool | None = None, with_row_id: bool | None = None, with_row_address: bool | None = None, use_stats: bool | None = None, full_text_query: str | dict | None = None, io_buffer_size: int | None = None, late_materialization: bool | list[str] | None = None, use_scalar_index: bool | None = None, strict_batch_size: bool | None = None, **kwargs) Iterator[RecordBatch]

将数据集读取为物化的记录批次。

Parameters:
**kwargs : dict, optional

scanner()的参数。

Returns:

record_batches

Return type:

RecordBatch的迭代器

LanceDataset.to_table(columns: list[str] | dict[str, str] | None = None, filter: 表达式 | str | None = None, limit: int | None = None, offset: int | None = None, nearest: dict | None = None, batch_size: int | None = None, batch_readahead: int | None = None, fragment_readahead: int | None = None, scan_in_order: bool | None = None, *, prefilter: bool | None = None, with_row_id: bool | None = None, with_row_address: bool | None = None, use_stats: bool | None = None, fast_search: bool | None = None, full_text_query: str | dict | FullTextQuery | None = None, io_buffer_size: int | None = None, late_materialization: bool | list[str] | None = None, use_scalar_index: bool | None = None, include_deleted_rows: bool | None = None) 表格

将数据作为pyarrow.Table读入内存

Parameters:
columns : list of str, or dict of str to str default None

要获取的列名列表。 或者列名到SQL表达式的字典。 如果为None或未指定,则获取所有列。

filter : pa.compute.Expression or str

表达式或字符串,必须是一个有效的SQL where子句。有关有效的SQL表达式,请参阅 Lance filter pushdown

limit : int, default None

最多获取这么多行。如果为None或未指定,则获取所有行。

offset : int, default None

从这一行开始获取。如果未指定则为0。

nearest : dict, default None

获取与K个最相似向量对应的行。示例:

{
    "column": <embedding col name>,
    "q": <query vector as pa.Float32Array>,
    "k": 10,
    "metric": "cosine",
    "minimum_nprobes": 20,
    "maximum_nprobes": 50,
    "refine_factor": 1
}

batch_size : int, optional

每次读取的行数。

io_buffer_size : int, default None

IO缓冲区的大小。有关更多信息,请参阅ScannerBuilder.io_buffer_size

batch_readahead : int, optional

预读取的批次数量。

fragment_readahead : int, optional

预读取的片段数量。

scan_in_order : bool, optional, default True

是否按顺序读取片段和批次。如果为false,吞吐量可能会更高,但批次将无序返回,内存使用可能会增加。

prefilter : bool, optional, default False

在向量搜索之前运行过滤器。

late_materialization : bool or List[str], default None

允许自定义控制延迟物化。更多信息请参阅 ScannerBuilder.late_materialization

use_scalar_index : bool, default True

允许自定义控制标量索引的使用。更多信息请参见 ScannerBuilder.use_scalar_index

with_row_id : bool, optional, default False

返回行ID。

with_row_address : bool, optional, default False

返回行地址

use_stats : bool, optional, default True

在过滤过程中使用统计下推。

full_text_query : str or dict, optional

用于搜索的查询字符串,结果将按BM25算法排序。 例如:"hello world"会匹配包含"hello"或"world"的文档。 或者使用包含以下键的字典:

  • columns: list[str]

    要搜索的列, 目前仅支持在列列表中指定单个列。

  • query: str

    要搜索的查询字符串。

include_deleted_rows : bool, optional, default False

如果为True,则已被删除但仍存在于片段中的行将被返回。这些行的_rowid列将被设为null。所有其他列将反映磁盘上存储的值,可能不为null。

注意:如果是搜索操作或take操作(包括标量索引扫描),则无法返回已删除的行。

笔记

如果同时指定了filter和nearest,那么:

  1. nearest 会优先执行。

  2. 除非将pre-filter设置为True,否则结果会在之后进行过滤。

随机访问

与其他列式存储格式不同,Lance凭借其超快的随机访问能力脱颖而出。

LanceDataset.take(索引: list[int] | 数组, columns: list[str] | dict[str, str] | None = None) 表格

按索引选择数据行。

Parameters:
indices : Array or array-like

数据集中要选择的行索引。

columns : list of str, or dict of str to str default None

要获取的列名列表。 或者列名到SQL表达式的字典。 如果为None或未指定,则获取所有列。

Returns:

表格

Return type:

pyarrow.Table

LanceDataset.take_blobs(blob_column: str, ids: list[int] | 数组 | None = None, 地址: list[int] | 数组 | None = None, 索引: list[int] | 数组 | None = None) list[BlobFile]

按行ID选择二进制大对象。

无需在处理前将大型二进制blob数据加载到内存中,该API允许您将二进制blob数据作为常规的Python类文件对象打开。更多详情请参阅lance.BlobFile

必须且只能指定ids、addresses或indices中的一个参数。 :param blob_column: 要选择的blob列名称。 :type blob_column: str :param ids: 数据集中要选择的行ID。 :type ids: Integer Array或类似数组 :param addresses: 数据集中要选择行的(不稳定)内存地址。 :type addresses: Integer Array或类似数组 :param indices: 数据集中行的偏移量/索引。 :type indices: Integer Array或类似数组

Returns:

blob_files

Return type:

列表[BlobFile]

模式演进

Lance支持模式演进,这意味着您可以低成本地向数据集添加新列。

LanceDataset.add_columns(转换: dict[str, str] | BatchUDF | ReaderLike | pyarrow.Field | list[pyarrow.Field] | pyarrow.Schema, read_columns: list[str] | None = None, reader_schema: pa.Schema | None = None, batch_size: int | None = None)

使用定义的值添加新列。

有几种方式可以指定新列。首先,可以为每个新列提供SQL表达式。其次,可以提供一个UDF(用户定义函数),该函数接收一批现有数据并返回包含新列的新数据批次。这些新列将被追加到数据集中。

你也可以提供一个RecordBatchReader,它将从某个外部源读取新列的值。当新列的值已经暂存到文件中(通常由某个分布式进程完成)时,这通常很有用。

有关编写UDF的更多信息,请参阅lance.add_columns_udf()装饰器。

Parameters:
transforms : dict or AddColumnsUDF or ReaderLike

如果这是一个字典,那么键是新列的名称,值则是SQL表达式字符串。这些字符串可以引用数据集中的现有列。 如果这是一个AddColumnsUDF,那么它是一个用户定义函数,接收一批现有数据并返回包含新列的新数据批次。 如果这是pyarrow.Fieldpyarrow.Schema,则会以仅元数据操作的方式添加所有具有给定模式的NULL列。

read_columns : list of str, optional

UDF将读取的列名。如果为None,则UDF将读取所有列。仅当transforms是UDF时使用此参数。否则,读取的列将从SQL表达式中推断得出。

reader_schema : pa.Schema, optional

仅当transforms是ReaderLike对象时有效。这将用于确定读取器的模式。

batch_size : int, optional

在应用转换时,每次从源数据集中读取的行数。如果数据集是v1版本,则忽略此参数。

示例

>>> import lance
>>> import pyarrow as pa
>>> table = pa.table({"a": [1, 2, 3]})
>>> dataset = lance.write_dataset(table, "my_dataset")
>>> @lance.batch_udf()
... def double_a(batch):
...     df = batch.to_pandas()
...     return pd.DataFrame({'double_a': 2 * df['a']})
>>> dataset.add_columns(double_a)
>>> dataset.to_table().to_pandas()
   a  double_a
0  1         2
1  2         4
2  3         6
>>> dataset.add_columns({"triple_a": "a * 3"})
>>> dataset.to_table().to_pandas()
   a  double_a  triple_a
0  1         2         3
1  2         4         6
2  3         6         9

另请参阅

LanceDataset.merge

将一组预先计算好的列合并到数据集中。

LanceDataset.drop_columns(columns: list[str])

从数据集中删除一列或多列

这是一个仅涉及元数据的操作,不会从底层存储中删除实际数据。如需删除数据,您必须随后调用compact_files来重写不包含被删除列的数据,然后调用cleanup_old_versions来移除旧文件。

Parameters:
columns : list of str

要删除的列名。这些可以是嵌套列引用(例如“a.b.c”)或顶级列名(例如“a”)。

示例

>>> import lance
>>> import pyarrow as pa
>>> table = pa.table({"a": [1, 2, 3], "b": ["a", "b", "c"]})
>>> dataset = lance.write_dataset(table, "example")
>>> dataset.drop_columns(["a"])
>>> dataset.to_table().to_pandas()
   b
0  a
1  b
2  c

索引与搜索

LanceDataset.create_index(: str | list[str], index_type: str, name: str | None = None, metric: str = 'L2', replace: bool = False, num_partitions: int | None = None, ivf_centroids: np.ndarray | pa.FixedSizeListArray | pa.FixedShapeTensorArray | None = None, pq_codebook: np.ndarray | pa.FixedSizeListArray | pa.FixedShapeTensorArray | None = None, num_sub_vectors: int | None = None, accelerator: str | 'torch.Device' | None = None, index_cache_size: int | None = None, shuffle_partition_batches: int | None = None, shuffle_partition_concurrency: int | None = None, ivf_centroids_file: str | None = None, precomputed_partition_dataset: str | None = None, storage_options: dict[str, str] | None = None, filter_nan: bool = True, one_pass_ivfpq: bool = False, **kwargs) LanceDataset

在列上创建索引。

实验性API

Parameters:
column : str

要建立索引的列。

index_type : str

索引的类型。 "IVF_PQ, IVF_HNSW_PQ IVF_HNSW_SQ" 目前支持。

name : str, optional

索引名称。如果未提供,将根据列名自动生成。

metric : str

距离度量类型,即“L2”(“euclidean”的别名)、“cosine”或“dot”(点积)。默认为“L2”。

replace : bool

如果索引已存在,则替换现有索引。

num_partitions : int, optional

IVF(倒排文件索引)的分区数量。

ivf_centroids : optional

它可以是np.ndarraypyarrow.FixedSizeListArraypyarrow.FixedShapeTensorArray。 一个num_partitions x dimension维度的现有K均值中心点数组, 用于IVF聚类。如果未提供,将训练一个新的KMeans模型。

pq_codebook : optional,

它可以是np.ndarraypyarrow.FixedSizeListArray, 或pyarrow.FixedShapeTensorArray。 一个num_sub_vectors x (2 ^ nbits * dimensions // num_sub_vectors) 数组,表示PQ码本的K均值中心点。

注意:目前nbits始终为8。 如果未提供,将训练一个新的PQ模型。

num_sub_vectors : int, optional

PQ(乘积量化)的子向量数量。

accelerator: str | 'torch.Device' | None = None

如果设置,将使用加速器来加快训练过程。 支持的加速器包括:"cuda"(英伟达GPU)和"mps"(苹果硅GPU)。 如果未设置,则使用CPU。

index_cache_size : int, optional

索引缓存的大小,以条目数表示。默认值为256。

shuffle_partition_batches : int, optional

批次数,使用数据集的row group大小,决定每个shuffle分区包含的数量。默认值为10240。

假设row group大小为1024,每个shuffle分区将包含10240 * 1024 = 10,485,760行。减小此值会减少shuffle操作的内存消耗但会增加完成时间,反之亦然。

shuffle_partition_concurrency : int, optional

并发处理的shuffle分区数量。默认值为2

减小该值可以减少shuffle操作的内存消耗,但会增加完成时间,反之亦然。

storage_options : optional, dict

针对特定存储连接的额外选项。这用于存储连接参数,如凭证、端点等。

filter_nan : bool

默认为True。False是不安全的,如果存在任何null/nan值会导致崩溃(否则不会)。禁用用于可空列的空值过滤器。可获得小幅速度提升。

one_pass_ivfpq : bool

默认为False。如果启用,索引类型必须为“IVF_PQ”。可减少磁盘IO。

**kwargs

传递给索引构建过程的参数。

SQ(标量量化)仅适用于IVF_HNSW_SQ索引类型,这种量化方法用于减少索引的内存占用,它将浮点向量映射为整数向量,每个整数占用num_bits位,目前仅支持8位。

If index_type is “IVF_*”, then the following parameters are required:

num_partitions

If index_type is with “PQ”, then the following parameters are required:

子向量数量

IVF_PQ的可选参数:

  • ivf_centroids

    用于IVF聚类的现有K均值中心点。

  • num_bits

    PQ(乘积量化)的位数。默认为8。 仅支持4和8。

Optional parameters for IVF_HNSW_*:
max_level

Int,图中最大层级数。

m

Int,图中每个节点的边数。

ef_construction

Int,构建过程中需要检查的节点数量。

示例

import lance

dataset = lance.dataset("/tmp/sift.lance")
dataset.create_index(
    "vector",
    "IVF_PQ",
    num_partitions=256,
    num_sub_vectors=16
)
import lance

dataset = lance.dataset("/tmp/sift.lance")
dataset.create_index(
    "vector",
    "IVF_HNSW_SQ",
    num_partitions=256,
)

实验性加速器(GPU)支持:

  • accelerate: 使用GPU训练IVF分区。

    目前仅支持CUDA(英伟达)或MPS(苹果)平台。 需要安装PyTorch。

import lance

dataset = lance.dataset("/tmp/sift.lance")
dataset.create_index(
    "vector",
    "IVF_PQ",
    num_partitions=256,
    num_sub_vectors=16,
    accelerator="cuda"
)

参考文献

LanceDataset.create_scalar_index(: str, index_type: 'BTREE' | 'BITMAP' | 'LABEL_LIST' | 'INVERTED' | 'FTS' | 'NGRAM', name: str | None = None, *, replace: bool = True, **kwargs)

在列上创建标量索引。

标量索引与向量索引类似,可用于加速扫描。当扫描包含对已索引列的过滤表达式时,标量索引能显著提升查询速度。例如,若my_col列建有标量索引,以下扫描操作将执行得更快:

import lance

dataset = lance.dataset("/tmp/images.lance")
my_table = dataset.scanner(filter="my_col != 7").to_table()

带有预过滤器的向量搜索也可以从标量索引中受益。例如,

import lance

dataset = lance.dataset("/tmp/images.lance")
my_table = dataset.scanner(
    nearest=dict(
       column="vector",
       q=[1, 2, 3, 4],
       k=10,
    )
    filter="my_col != 7",
    prefilter=True
)

目前有5种标量索引类型可供选择。

  • BTREE。最常见的类型是BTREE。该索引的灵感来源于btree数据结构,尽管只有btree的前几层会被缓存在内存中。它将在具有大量唯一值且每个值对应行数较少的列上表现良好。

  • BITMAP。该索引为列中的每个唯一值存储一个位图。这种索引适用于具有少量唯一值且每个值对应多行数据的列。

  • LABEL_LIST. 一种特殊索引,用于对值基数较小的列表列进行索引。例如,包含标签列表的列(如["tag1", "tag2", "tag3"])可以使用LABEL_LIST索引。该索引只能加速带有array_has_anyarray_has_all过滤器的查询。

  • NGRAM. 一种用于索引字符串列的特殊索引。该索引会为字符串中的每个n元语法创建位图。默认情况下我们使用三元语法。当前该索引可以加速在过滤器中使用contains函数的查询。

  • FTS/INVERTED. 该索引用于对文档列进行索引。这种索引可以进行全文搜索。例如,一个包含查询字符串"hello world"中任意单词的列。结果将按BM25算法排序。

请注意,可以使用环境变量LANCE_BYPASS_SPILLING来绕过磁盘溢出。将其设置为true可以避免内存耗尽问题(更多信息请参阅https://github.com/apache/datafusion/issues/10073)。

实验性API

Parameters:
column : str

要建立索引的列。必须是布尔型、整型、浮点型或字符串类型的列。

index_type : str

索引的类型。可选值为 "BTREE", "BITMAP", "LABEL_LIST", "NGRAM", "FTS""INVERTED"

name : str, optional

索引名称。如果未提供,将根据列名自动生成。

replace : bool, default True

如果索引已存在,则替换现有索引。

with_position : bool, default True

这是针对INVERTED索引的。如果设为True,索引将存储文档中单词的位置信息,以便支持短语查询。这将显著增加索引大小。即使设置为True,也不会影响非短语查询的性能。

base_tokenizer : str, default "simple"

这是针对INVERTED索引的配置。指定使用的基础分词器,可选值包括: * "simple":根据空白字符和标点符号进行分词。 * "whitespace":仅根据空白字符进行分词。 * "raw":不进行分词处理。

language : str, default "English"

这是针对INVERTED索引的。用于词干提取和停用词处理的语言。仅当stemremove_stop_words为true时使用

max_token_length : Optional[int], default 40

这是针对INVERTED索引的设置。表示最大令牌长度。任何超过此长度的令牌将被移除。

lower_case : bool, default True

这是针对INVERTED索引的。如果设为True,索引会将所有文本转换为小写。

stem : bool, default False

这是针对INVERTED索引的。如果为True,索引将对词干进行提取。

remove_stop_words : bool, default False

这是针对INVERTED索引的。如果为True,该索引将移除停用词。

ascii_folding : bool, default False

这是针对INVERTED索引的。如果设为True,索引会尽可能将非ASCII字符转换为ASCII字符。例如会将带重音符号的字母如"é"转换为"e"。

示例

import lance

dataset = lance.dataset("/tmp/images.lance")
dataset.create_index(
    "category",
    "BTREE",
)

标量索引只能加速使用等值、比较、范围(例如my_col BETWEEN 0 AND 100)和集合成员(例如my_col IN (0, 1, 2))等基础过滤条件的扫描

当筛选条件包含多个索引列且这些条件通过AND或OR逻辑连接时,可以使用标量索引 (例如 my_col < 0 AND other_col> 100)

如果过滤条件包含未建立索引的列,虽然可以使用标量索引,但根据过滤条件的结构,可能无法实际使用。例如,若列not_indexed没有标量索引,那么过滤条件my_col = 0 OR not_indexed = 1将无法利用my_col上的任何标量索引。

要判断扫描是否使用了标量索引,可以使用explain_plan查看lancedb生成的查询计划。使用标量索引的查询将包含ScalarIndexQuery关系或MaterializeIndex操作符。

LanceDataset.drop_index(name: str)

从数据集中删除索引

注意:索引是通过"索引名称"删除的。这与字段名称不同。如果在创建索引时未指定名称,则会自动生成一个名称。您可以使用list_indices方法来获取索引的名称。

LanceDataset.scanner(columns: list[str] | dict[str, str] | None = None, filter: 表达式 | str | None = None, limit: int | None = None, offset: int | None = None, nearest: dict | None = None, batch_size: int | None = None, batch_readahead: int | None = None, fragment_readahead: int | None = None, scan_in_order: bool | None = None, 片段: Iterable[LanceFragment] | None = None, full_text_query: str | dict | FullTextQuery | None = None, *, prefilter: bool | None = None, with_row_id: bool | None = None, with_row_address: bool | None = None, use_stats: bool | None = None, fast_search: bool | None = None, io_buffer_size: int | None = None, late_materialization: bool | list[str] | None = None, use_scalar_index: bool | None = None, include_deleted_rows: bool | None = None, scan_stats_callback: Callable[[ScanStatistics], None] | None = None, strict_batch_size: bool | None = None) LanceScanner

返回一个支持各种下推操作的Scanner。

Parameters:
columns : list of str, or dict of str to str default None

要获取的列名列表。 或者列名到SQL表达式的字典。 如果为None或未指定,则获取所有列。

filter : pa.compute.Expression or str

表达式或字符串,必须是一个有效的SQL where子句。有关有效的SQL表达式,请参阅 Lance filter pushdown

limit : int, default None

最多获取这么多行。如果为None或未指定,则获取所有行。

offset : int, default None

从这一行开始获取。如果未指定则为0。

nearest : dict, default None

获取与K个最相似向量对应的行。示例:

{
    "column": <embedding col name>,
    "q": <query vector as pa.Float32Array>,
    "k": 10,
    "minimum_nprobes": 20,
    "maximum_nprobes": 50,
    "refine_factor": 1
}

batch_size : int, default None

返回批次的目标大小。在某些情况下,批次大小可能达到此值的两倍(但绝不会超过)。而在其他情况下,批次大小可能小于此值。

io_buffer_size : int, default None

IO缓冲区的大小。有关更多信息,请参阅ScannerBuilder.io_buffer_size

batch_readahead : int, optional

预读取的批次数量。

fragment_readahead : int, optional

预读取的片段数量。

scan_in_order : bool, default True

是否按顺序读取片段和批次。如果为false,吞吐量可能会更高,但批次将无序返回,内存使用可能会增加。

fragments : iterable of LanceFragment, default None

如果指定,则仅扫描这些片段。如果scan_in_order为True,那么片段将按照给定的顺序进行扫描。

prefilter : bool, default False

如果为True,则在运行向量查询之前应用过滤器。 这将生成更准确的结果,但查询成本可能更高。 通常在过滤器具有高选择性时效果良好。

如果为False,则在运行向量查询之后应用过滤器。 这样性能会更好,但如果最接近查询的行不匹配过滤器, 结果可能会少于请求的行数(或为空)。 通常在过滤器选择性不高时效果良好。

use_scalar_index : bool, default True

Lance会自动使用标量索引来优化查询。在某些极端情况下,这可能会使查询性能变差,此时可以通过该参数禁用标量索引。

late_materialization : bool or List[str], default None

允许自定义控制延迟物化。延迟物化会在过滤操作后通过take操作获取非查询列,这在结果较少或列数据量非常大时非常有用。

当结果较多或列数据非常窄时,早期物化可能更优。

如果设为True,则所有列都采用延迟物化; 如果设为False,则所有列都采用早期物化; 如果是字符串列表,则只有列表中的列会延迟物化。

默认采用启发式算法,假设过滤器会筛选出约0.1%的行。如果您的过滤器选择性更强(例如按id查找),可能需要设为True;如果过滤器选择性较弱(例如匹配20%的行),可能需要设为False。

full_text_query : str or dict, optional

要搜索的查询字符串,结果将按BM25算法排序。 例如"hello world"会匹配包含"hello"或"world"的文档。 或者使用包含以下键的字典:

  • columns: list[str]

    要搜索的列, 目前columns列表中仅支持单个列。

  • query: str

    要搜索的查询字符串。

如果为True,则搜索将仅在索引数据上执行,这样可以缩短搜索时间。

scan_stats_callback : Callable[[ScanStatistics], None], default None

一个回调函数,在扫描完成后将调用该函数并传入扫描统计信息。回调函数引发的错误将被记录但不会重新抛出。

include_deleted_rows : bool, default False

如果为True,则已被删除但仍存在于片段中的行将被返回。这些行的_rowid列将被设为null。所有其他列将反映磁盘上存储的值,可能不为null。

注意:如果是搜索操作或take操作(包括标量索引扫描),则无法返回已删除的行。

注意

目前,如果同时指定了filter和nearest,那么:

  1. nearest 会优先执行。

  2. 结果会在之后进行过滤。

为了调试近似最近邻(ANN)结果,您可以选择即使存在索引也不使用它,只需指定use_index=False。例如,以下代码将始终返回精确的KNN结果:

dataset.to_table(nearest={
    "column": "vector",
    "k": 10,
    "q": <query vector>,
    "use_index": False
}

API参考

更多信息可在API reference中找到。