Бөлісу құралы:


Векторное хранилище в Azure Cosmos DB для виртуального ядра MongoDB

Область применения: Виртуальные ядра MongoDB

Используйте встроенную векторную базу данных в Azure Cosmos DB для виртуальных ядер MongoDB, чтобы легко подключать приложения на основе искусственного интеллекта с данными, хранящимися в Azure Cosmos DB. Эта интеграция может включать приложения, созданные с помощью внедрения Azure OpenAI. Встроенная векторная база данных позволяет эффективно хранить, индексировать и запрашивать высокомерные векторные данные, хранящиеся непосредственно в Azure Cosmos DB для виртуальных ядер MongoDB, а также исходные данные, из которых создаются векторные данные. Это устраняет необходимость передачи данных в альтернативные векторные хранилища и нанести дополнительные расходы.

Что такое хранилище векторов?

Векторное хранилище или векторная база данных — это база данных , предназначенная для хранения векторных внедрения и управления ими, которые являются математическими представлениями данных в высокомерном пространстве. В этом пространстве каждое измерение соответствует признаку данных, а для представления сложных данных можно использовать десятки тысяч измерений. Позиция вектора в этом пространстве представляет свои характеристики. Слова, фразы или целые документы, изображения, аудио и другие типы данных могут быть векторизированы.

Как работает векторное хранилище?

В хранилище векторов алгоритмы поиска векторов используются для индексирования и внедрения запросов. Некоторые известные алгоритмы поиска векторов включают иерархический навигационно-небольшой мир (HNSW), инвертированные файлы (IVF), DiskANN и т. д. Векторный поиск — это метод, который помогает находить аналогичные элементы на основе их характеристик данных, а не по точным совпадениям в поле свойства. Этот метод полезен в таких приложениях, как поиск аналогичного текста, поиск связанных изображений, рекомендации или даже обнаружение аномалий. Он используется для запроса векторных внедрения (списков чисел) данных, созданных с помощью модели машинного обучения с помощью API внедрения. Примерами api внедрения являются внедрение Azure OpenAI Embeddings или Hugging Face в Azure. Векторный поиск измеряет расстояние между векторами данных и вектором запроса. Векторы данных, близкие к вектору запросов, являются наиболее похожими семантикой.

В интегрированной базе данных векторов в Azure Cosmos DB для виртуальных ядер MongoDB внедрение можно хранить, индексировать и запрашивать вместе с исходными данными. Этот подход устраняет дополнительные затраты на репликацию данных в отдельной базе данных чистого вектора. Кроме того, эта архитектура сохраняет векторные внедрения и исходные данные вместе, что упрощает операции с несколькими модальными данными и обеспечивает более высокую согласованность данных, масштабирование и производительность.

Создание векторного индекса

Чтобы выполнить поиск по вектору по свойствам вектора в документах, необходимо сначала создать векторный индекс.

Создание векторного индекса с помощью HNSW

Вы можете создавать (иерархические индексы малого мира) на уровнях кластера M40 и более поздних версиях. Чтобы создать индекс HSNW, необходимо создать векторный индекс с параметром "kind" , заданным "vector-hnsw" в следующем шаблоне:

{ 
    "createIndexes": "<collection_name>",
    "indexes": [
        {
            "name": "<index_name>",
            "key": {
                "<path_to_property>": "cosmosSearch"
            },
            "cosmosSearchOptions": { 
                "kind": "vector-hnsw", 
                "m": <integer_value>, 
                "efConstruction": <integer_value>, 
                "similarity": "<string_value>", 
                "dimensions": <integer_value> 
            } 
        } 
    ] 
}
Поле Тип Описание:
index_name строка Уникальное имя индекса.
path_to_property строка Путь к свойству, содержаму вектору. Этот путь может быть свойством верхнего уровня или путем нотации точек к свойству. Если используется путь нотации точек, все нелиафетные элементы не могут быть массивами. Векторы должны быть number[] индексированы и возвращаться в результатах векторного поиска.
kind строка Тип создаваемого векторного индекса. Возможные значения: vector-ivf и vector-hnsw. Примечание vector-ivf доступно на всех уровнях кластера и vector-hnsw доступно на уровнях кластера M40 и более поздних версиях.
m integer Максимальное число подключений на слой (16 по умолчанию минимальное значение равно 2максимальному значению 100). Более высокий m подходит для наборов данных с высокими размерностью и (или) высокими требованиями к точности.
efConstruction integer Размер динамического списка кандидатов для создания графа (64 по умолчанию минимальное значение равно 4, максимальное значение 1000). Более efConstruction высокое качество индекса и более высокая точность, но также увеличит время, необходимое для построения индекса. efConstruction должен быть по крайней мере 2 * m
similarity строка Метрика сходства, используемая с индексом. Возможные варианты: COS (косинус расстояние), L2 (Евклидеан расстояние) и IP (внутренний продукт).
dimensions integer Число измерений для сходства векторов. Максимальное число поддерживаемых измерений .2000

Выполнение векторного поиска с помощью HNSW

Чтобы выполнить векторный поиск, используйте $search этап конвейера агрегирования запроса с оператором cosmosSearch .

{
    "$search": {
        "cosmosSearch": {
            "vector": <query_vector>,
            "path": "<path_to_property>",
            "k": <num_results_to_return>,
            "efSearch": <integer_value>
        },
    }
  }
}

Поле Тип Описание
efSearch integer Размер динамического списка кандидатов для поиска (40 по умолчанию). Более высокое значение обеспечивает лучшее отзыв по стоимости скорости.
k integer Количество возвращаемых результатов. оно должно быть меньше или равно efSearch

Примечание.

Создание индекса HSNW с большими наборами данных может привести к тому, что ресурс Azure Cosmos DB для виртуального ядра MongoDB не хватает памяти или может ограничить производительность других операций, выполняемых в базе данных. При возникновении таких проблем их можно устранить, масштабируя ресурс до более высокого уровня кластера или уменьшая размер набора данных.

Создание векторного индекса с помощью IVF

Чтобы создать векторный индекс с помощью алгоритма IVF (инвертированного файла), используйте следующий createIndexes шаблон и задайте "kind" для параметра значение "vector-ivf":

{
  "createIndexes": "<collection_name>",
  "indexes": [
    {
      "name": "<index_name>",
      "key": {
        "<path_to_property>": "cosmosSearch"
      },
      "cosmosSearchOptions": {
        "kind": "vector-ivf",
        "numLists": <integer_value>,
        "similarity": "<string_value>",
        "dimensions": <integer_value>
      }
    }
  ]
}
Поле Тип Описание:
index_name строка Уникальное имя индекса.
path_to_property строка Путь к свойству, содержаму вектору. Этот путь может быть свойством верхнего уровня или путем нотации точек к свойству. Если используется путь нотации точек, все нелиафетные элементы не могут быть массивами. Векторы должны быть number[] индексированы и возвращаться в результатах векторного поиска.
kind строка Тип создаваемого векторного индекса. Возможные значения: vector-ivf и vector-hnsw. Примечание vector-ivf доступно на всех уровнях кластера и vector-hnsw доступно на уровнях кластера M40 и более поздних версиях.
numLists integer Это целое число — это количество кластеров, которые индекс инвертированного файла (IVF) использует для группировки векторных данных. numLists Рекомендуется установить documentCount/1000 до 1 миллиона документов и sqrt(documentCount) для более чем 1 миллиона документов. numLists Использование значения 1 — это похоже на выполнение поиска подбора, который имеет ограниченную производительность.
similarity строка Метрика сходства, используемая с индексом. Возможные варианты: COS (косинус расстояние), L2 (Евклидеан расстояние) и IP (внутренний продукт).
dimensions integer Число измерений для сходства векторов. Максимальное число поддерживаемых измерений .2000

Внимание

Правильное задание параметра numLists важно для достижения хорошей точности и производительности. numLists Рекомендуется установить documentCount/1000 до 1 миллиона документов и sqrt(documentCount) для более чем 1 миллиона документов.

По мере роста числа элементов в базе данных необходимо настроить числовые списки, чтобы обеспечить высокую производительность задержки для поиска векторов .

Если вы экспериментируете с новым сценарием или создаете небольшую демонстрацию, можно начать с numLists задания для 1 выполнения подбора принудительного поиска по всем векторам. Это должно обеспечить наиболее точные результаты из векторного поиска, однако помните, что скорость поиска и задержка будут медленными. После первоначальной настройки необходимо перейти к numLists настройке параметра, используя приведенные выше рекомендации.

Выполнение векторного поиска с помощью IVF

Чтобы выполнить векторный поиск, используйте $search этап конвейера агрегирования в запросе MongoDB. Чтобы использовать cosmosSearch индекс, используйте новый cosmosSearch оператор.

{
  {
  "$search": {
    "cosmosSearch": {
        "vector": <query_vector>,
        "path": "<path_to_property>",
        "k": <num_results_to_return>,
      },
      "returnStoredSource": True }},
  {
    "$project": { "<custom_name_for_similarity_score>": {
           "$meta": "searchScore" },
            "document" : "$$ROOT"
        }
  }
}

Чтобы получить оценку сходства (searchScore) вместе с документами, найденными векторным поиском, используйте $project оператор, чтобы включить searchScore и переименовать его как <custom_name_for_similarity_score> в результатах. Затем документ также проецируется как вложенный объект. Обратите внимание, что оценка сходства вычисляется с помощью метрики, определенной в индексе вектора.

Внимание

Векторы должны быть number[] индексированы. Использование другого типа, например double[], предотвращает индексирование документа. Неиндексированные документы не будут возвращены в результате векторного поиска.

Пример использования индекса HNSW.

В следующих примерах показано, как индексировать векторы, добавлять документы с свойствами векторов, выполнять векторный поиск и извлекать конфигурацию индекса.

use test;

db.createCollection("exampleCollection");

db.runCommand({ 
    "createIndexes": "exampleCollection",
    "indexes": [
        {
            "name": "VectorSearchIndex",
            "key": {
                "contentVector": "cosmosSearch"
            },
            "cosmosSearchOptions": { 
                "kind": "vector-hnsw", 
                "m": 16, 
                "efConstruction": 64, 
                "similarity": "COS", 
                "dimensions": 3
            } 
        } 
    ] 
});

Эта команда создает индекс HNSW для contentVector свойства в документах, хранящихся в указанной коллекции. exampleCollection Свойство cosmosSearchOptions задает параметры для векторного индекса HNSW. Если в документе есть вектор, хранящийся в вложенном свойстве, можно задать это свойство с помощью пути нотации точек. Например, можно использовать text.contentVector , если contentVector является подпропастерием text.

Добавление векторов в базу данных

Чтобы добавить векторы в коллекцию базы данных, сначала необходимо создать внедрения с помощью собственной модели, Azure OpenAI Embeddings или другого API (например , обнимать лицо в Azure). В этом примере новые документы добавляются с помощью примеров внедрения:

db.exampleCollection.insertMany([
  {name: "Eugenia Lopez", bio: "Eugenia is the CEO of AdvenureWorks.", vectorContent: [0.51, 0.12, 0.23]},
  {name: "Cameron Baker", bio: "Cameron Baker CFO of AdvenureWorks.", vectorContent: [0.55, 0.89, 0.44]},
  {name: "Jessie Irwin", bio: "Jessie Irwin is the former CEO of AdventureWorks and now the director of the Our Planet initiative.", vectorContent: [0.13, 0.92, 0.85]},
  {name: "Rory Nguyen", bio: "Rory Nguyen is the founder of AdventureWorks and the president of the Our Planet initiative.", vectorContent: [0.91, 0.76, 0.83]},
]);

Продолжая последний пример, создайте другой вектор. queryVector Векторный поиск измеряет расстояние между queryVector векторами в contentVector пути к документам. Можно задать количество результатов, возвращаемых поиском k, задав параметр, который задан здесь 2 . Можно также задать efSearchцелое число, которое управляет размером списка векторов кандидатов. Более высокое значение может повысить точность, однако поиск будет медленнее в результате. Это необязательный параметр со значением по умолчанию 40.

const queryVector = [0.52, 0.28, 0.12];
db.exampleCollection.aggregate([
  {
    "$search": {
        "cosmosSearch": {
            "vector": "queryVector",
            "path": "contentVector",
            "k": 2,
            "efSearch": 40
        },
    }
  }
}
]);

В этом примере поиск вектора выполняется с помощью queryVector входных данных через оболочку Mongo. Результат поиска — это список двух элементов, которые наиболее похожи на вектор запроса, отсортированные по их оценке сходства.

[
  {
    similarityScore: 0.9465376,
    document: {
      _id: ObjectId("645acb54413be5502badff94"),
      name: 'Eugenia Lopez',
      bio: 'Eugenia is the CEO of AdvenureWorks.',
      vectorContent: [ 0.51, 0.12, 0.23 ]
    }
  },
  {
    similarityScore: 0.9006955,
    document: {
      _id: ObjectId("645acb54413be5502badff97"),
      name: 'Rory Nguyen',
      bio: 'Rory Nguyen is the founder of AdventureWorks and the president of the Our Planet initiative.',
      vectorContent: [ 0.91, 0.76, 0.83 ]
    }
  }
]

Получение определений векторного индекса

Чтобы получить определение векторного индекса из коллекции, используйте listIndexes команду:

db.exampleCollection.getIndexes();

В этом примере vectorIndex возвращается все cosmosSearch параметры, которые использовались для создания индекса:

[
  { v: 2, key: { _id: 1 }, name: '_id_', ns: 'test.exampleCollection' },
  {
    v: 2,
    key: { contentVector: 'cosmosSearch' },
    name: 'vectorSearchIndex',
    cosmosSearch: {
      kind: 'vector-hnsw',
      m: 40,
      efConstruction: 64,
      similarity: 'COS',
      dimensions: 3
    },
    ns: 'test.exampleCollection'
  }
]

Пример использования индекса IVF

Индексирование инвертированного файла (IVF) — это метод, который упорядочивает векторы в кластерах. Во время векторного поиска векторный вектор сначала сравнивается с центрами этих кластеров. Затем поиск проводится в кластере, центр которого ближе всего к вектору запроса.

Параметр numLists определяет количество создаваемых кластеров. Один кластер подразумевает, что поиск выполняется по всем векторам в базе данных, а также к поиску подбора или kNN. Этот параметр обеспечивает максимальную точность, но и максимальную задержку.

Увеличение значения приводит к увеличению numLists числа кластеров, каждый из которых содержит меньше векторов. Например, если numLists=2каждый кластер содержит больше векторов, чем если numLists=3, и т. д. Меньше векторов на кластер ускоряет поиск (более низкая задержка, более высокие запросы в секунду). Однако это повышает вероятность отсутствия наиболее аналогичного вектора в базе данных с вектором запроса. Это связано с несовершенным характером кластеризации, где поиск может сосредоточиться на одном кластере, в то время как фактический "ближайший" вектор находится в другом кластере.

Параметр nProbes определяет количество кластеров для поиска. По умолчанию оно имеет значение 1, то есть выполняется поиск только в кластере с центром, ближайшим к вектору запроса. Увеличение этого значения позволяет поиску охватывать больше кластеров, повышая точность, но и увеличивая задержку (таким образом уменьшая запросы в секунду), так как выполняется поиск большего числа кластеров и векторов.

В следующих примерах показано, как индексировать векторы, добавлять документы с свойствами векторов, выполнять векторный поиск и извлекать конфигурацию индекса.

Создание векторного индекса

use test;

db.createCollection("exampleCollection");

db.runCommand({
  createIndexes: 'exampleCollection',
  indexes: [
    {
      name: 'vectorSearchIndex',
      key: {
        "vectorContent": "cosmosSearch"
      },
      cosmosSearchOptions: {
        kind: 'vector-ivf',
        numLists: 3,
        similarity: 'COS',
        dimensions: 3
      }
    }
  ]
});

Эта команда создает vector-ivf индекс для vectorContent свойства в документах, хранящихся в указанной коллекции. exampleCollection Свойство cosmosSearchOptions задает параметры для индекса вектора IVF. Если в документе есть вектор, хранящийся в вложенном свойстве, можно задать это свойство с помощью пути нотации точек. Например, можно использовать text.vectorContent , если vectorContent является подпропастерием text.

Добавление векторов в базу данных

Чтобы добавить векторы в коллекцию базы данных, сначала необходимо создать внедрения с помощью собственной модели, Azure OpenAI Embeddings или другого API (например , обнимать лицо в Azure). В этом примере новые документы добавляются с помощью примеров внедрения:

db.exampleCollection.insertMany([
  {name: "Eugenia Lopez", bio: "Eugenia is the CEO of AdvenureWorks.", vectorContent: [0.51, 0.12, 0.23]},
  {name: "Cameron Baker", bio: "Cameron Baker CFO of AdvenureWorks.", vectorContent: [0.55, 0.89, 0.44]},
  {name: "Jessie Irwin", bio: "Jessie Irwin is the former CEO of AdventureWorks and now the director of the Our Planet initiative.", vectorContent: [0.13, 0.92, 0.85]},
  {name: "Rory Nguyen", bio: "Rory Nguyen is the founder of AdventureWorks and the president of the Our Planet initiative.", vectorContent: [0.91, 0.76, 0.83]},
]);

Выполнение векторного поиска

Чтобы выполнить векторный поиск, используйте $search этап конвейера агрегирования в запросе MongoDB. Чтобы использовать cosmosSearch индекс, используйте новый cosmosSearch оператор.

{
  {
  "$search": {
    "cosmosSearch": {
        "vector": <vector_to_search>,
        "path": "<path_to_property>",
        "k": <num_results_to_return>,
      },
      "returnStoredSource": True }},
  {
    "$project": { "<custom_name_for_similarity_score>": {
           "$meta": "searchScore" },
            "document" : "$$ROOT"
        }
  }
}

Чтобы получить оценку сходства (searchScore) вместе с документами, найденными векторным поиском, используйте $project оператор, чтобы включить searchScore и переименовать его как <custom_name_for_similarity_score> в результатах. Затем документ также проецируется как вложенный объект. Обратите внимание, что оценка сходства вычисляется с помощью метрики, определенной в индексе вектора.

Продолжая последний пример, создайте другой вектор. queryVector Векторный поиск измеряет расстояние между queryVector векторами в vectorContent пути к документам. Можно задать количество результатов, возвращаемых поиском k, задав параметр, который задан здесь 2 . Можно также задать nProbesцелое число, которое управляет количеством близлежащих кластеров, которые проверяются в каждом поиске. Более высокое значение может повысить точность, однако поиск будет медленнее в результате. Это необязательный параметр со значением по умолчанию 1 и не может быть больше значения, указанного numLists в векторном индексе.

const queryVector = [0.52, 0.28, 0.12];
db.exampleCollection.aggregate([
  {
    $search: {
      "cosmosSearch": {
        "vector": queryVector,
        "path": "vectorContent",
        "k": 2
      },
    "returnStoredSource": true }},
  {
    "$project": { "similarityScore": {
           "$meta": "searchScore" },
            "document" : "$$ROOT"
        }
  }
]);

В этом примере поиск вектора выполняется с помощью queryVector входных данных через оболочку Mongo. Результат поиска — это список двух элементов, которые наиболее похожи на вектор запроса, отсортированные по их оценке сходства.

[
  {
    similarityScore: 0.9465376,
    document: {
      _id: ObjectId("645acb54413be5502badff94"),
      name: 'Eugenia Lopez',
      bio: 'Eugenia is the CEO of AdvenureWorks.',
      vectorContent: [ 0.51, 0.12, 0.23 ]
    }
  },
  {
    similarityScore: 0.9006955,
    document: {
      _id: ObjectId("645acb54413be5502badff97"),
      name: 'Rory Nguyen',
      bio: 'Rory Nguyen is the founder of AdventureWorks and the president of the Our Planet initiative.',
      vectorContent: [ 0.91, 0.76, 0.83 ]
    }
  }
]

Получение определений векторного индекса

Чтобы получить определение векторного индекса из коллекции, используйте listIndexes команду:

db.exampleCollection.getIndexes();

В этом примере vectorIndex возвращается все cosmosSearch параметры, которые использовались для создания индекса:

[
  { v: 2, key: { _id: 1 }, name: '_id_', ns: 'test.exampleCollection' },
  {
    v: 2,
    key: { vectorContent: 'cosmosSearch' },
    name: 'vectorSearchIndex',
    cosmosSearch: {
      kind: 'vector-ivf',
      numLists: 3,
      similarity: 'COS',
      dimensions: 3
    },
    ns: 'test.exampleCollection'
  }
]

Отфильтрованный векторный поиск (предварительная версия)

Теперь можно выполнять векторные поиски с помощью любого поддерживаемого фильтра запросов, например $lt, , $eq$lte, $neq, $gte, $nin$gt$inи .$regex Включите функцию "Фильтрация векторного поиска" на вкладке "Предварительные версии компонентов" подписки Azure. Дополнительные сведения о предварительных версиях функций см. здесь.

Во-первых, необходимо определить индекс для фильтра в дополнение к индексу вектора. Например, можно определить индекс фильтра для свойства.

db.runCommand({ 
     "createIndexes": "<collection_name",
    "indexes": [ {
        "key": { 
            "<property_to_filter>": 1 
               }, 
        "name": "<name_of_filter_index>" 
    }
    ] 
});

Затем можно добавить термин в векторный "filter" поиск, как показано ниже. В этом примере фильтр ищет документы, в которых "title" свойство не находится в списке ["not in this text", "or this text"].


db.exampleCollection.aggregate([
  {
      '$search': {
          "cosmosSearch": {
              "vector": "<query_vector>",
              "path": <path_to_vector>,
              "k": num_results,
              "filter": {<property_to_filter>: {"$nin": ["not in this text", "or this text"]}}
          },
          "returnStoredSource": True }},
      {'$project': { 'similarityScore': { '$meta': 'searchScore' }, 'document' : '$$ROOT' }
}
]);

Внимание

Хотя в предварительной версии отфильтрованный векторный поиск может потребовать настройки параметров индекса вектора для повышения точности. Например, увеличение mили efConstructionefSearch использование HNSW или numListsnProbes при использовании IVF может привести к улучшению результатов. Перед использованием необходимо протестировать конфигурацию, чтобы убедиться, что результаты удовлетворительны.

Использование средств оркестрации LLM

Использование векторной базы данных с семантическим ядром

Используйте семантический ядро для оркестрации получения информации из Azure Cosmos DB для виртуальных ядер MongoDB и LLM. Подробнее см. здесь.

https://github.com/microsoft/semantic-kernel/tree/main/python/semantic_kernel/connectors/memory/azure_cosmosdb

Использование векторной базы данных с LangChain

Используйте LangChain для оркестрации получения информации из Azure Cosmos DB для виртуальных ядер MongoDB и LLM. Подробнее см. здесь.

Использование в качестве семантического кэша с LangChain

Используйте LangChain и Azure Cosmos DB для MongoDB (vCore) для оркестрации семантического кэширования, используя ранее повторно созданные меры llM, которые могут сэкономить затраты на API LLM и сократить задержку для ответов. Дополнительные сведения см. здесь

Возможности и ограничения

  • Поддерживаемые метрики расстояния: L2 (Euclidean), внутренний продукт и косинус.
  • Поддерживаемые методы индексирования: IVFFLAT (GA) и HSNW (предварительная версия)
  • Индексирование векторов размером до 2000 измерений.
  • Индексирование применяется только к одному вектору на путь.
  • На векторный путь можно создать только один индекс.

Итоги

В этом руководстве показано, как создать векторный индекс, добавить документы с векторными данными, выполнить поиск сходства и получить определение индекса. Используя интегрированную базу данных векторов, вы можете эффективно хранить, индексировать и запрашивать высокомерные векторные данные непосредственно в Azure Cosmos DB для виртуальных ядер MongoDB. Это позволяет разблокировать полный потенциал данных с помощью векторных внедрения, и позволяет создавать более точные, эффективные и мощные приложения.

Следующий шаг