Skip to content
代码片段 群组 项目
未验证 提交 8ab8c2b4 编辑于 作者: Madelein van Niekerk's avatar Madelein van Niekerk 提交者: GitLab
浏览文件

Add conditional mapping for elasticsearch

Changelog: changed
EE: true

# Conflicts:
#	ee/lib/search/elastic/types/work_item.rb
#	ee/spec/lib/search/elastic/types/work_item_spec.rb
上级 a38d1e62
No related branches found
No related tags found
无相关合并请求
---
name: AddEmbeddingToWorkItems
version: '20241003142503'
description: Adds the embedding field to workitems index
group: group::global search
milestone: '17.5'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/163946
skippable: true
skip_condition: Must be on Elasticsearch 8+ or any version of OpenSearch
obsolete: false
marked_obsolete_by_url:
marked_obsolete_in_milestone:
# frozen_string_literal: true
class AddEmbeddingToWorkItems < Elastic::Migration
include Elastic::MigrationUpdateMappingsHelper
skip_if -> { !elasticsearch_8_plus? && !opensearch? }
def index_name
work_item_proxy.index_name
end
def new_mappings
mappings = if elasticsearch_8_plus?
work_item_proxy.elasticsearch_8_plus_mappings
else
work_item_proxy.opensearch_mappings
end
mappings.merge({ routing: { type: 'text' } })
end
end
private
def elasticsearch_8_plus?
helper.matching_distribution?(:elasticsearch, min_version: '8.0.0')
end
def opensearch?
helper.matching_distribution?(:opensearch)
end
def helper
@helper ||= Gitlab::Elastic::Helper.default
end
def work_item_proxy
Search::Elastic::Types::WorkItem
end
......@@ -34,6 +34,38 @@ def settings
)
end
def elasticsearch_8_plus_mappings(mappings = {})
return mappings unless helper.matching_distribution?(:elasticsearch, min_version: '8.0.0')
mappings.merge({
embedding_0: {
type: 'dense_vector',
dims: VERTEX_TEXT_EMBEDDING_DIMENSION,
similarity: 'cosine',
index: true
}
})
end
def opensearch_mappings(mappings = {})
return mappings unless helper.matching_distribution?(:opensearch)
mappings.merge({
embedding_0: {
type: 'knn_vector',
dimension: VERTEX_TEXT_EMBEDDING_DIMENSION,
method: {
name: 'hnsw',
space_type: 'cosinesimil',
parameters: {
ef_construction: OPENSEARCH_EF_CONSTRUCTION,
m: OPENSEARCH_M
}
}
}
})
end
private
def base_mappings
......@@ -68,38 +100,6 @@ def base_mappings
}
end
def elasticsearch_8_plus_mappings(mappings)
return mappings unless helper.matching_distribution?(:elasticsearch, min_version: '8.0.0')
mappings.merge({
embedding_0: {
type: 'dense_vector',
dims: VERTEX_TEXT_EMBEDDING_DIMENSION,
similarity: 'cosine',
index: true
}
})
end
def opensearch_mappings(mappings)
return mappings unless helper.matching_distribution?(:opensearch)
mappings.merge({
embedding_0: {
type: 'knn_vector',
dimension: VERTEX_TEXT_EMBEDDING_DIMENSION,
method: {
name: 'hnsw',
space_type: 'cosinesimil',
parameters: {
ef_construction: OPENSEARCH_EF_CONSTRUCTION,
m: OPENSEARCH_M
}
}
}
})
end
def helper
@helper ||= Gitlab::Elastic::Helper.default
end
......
# frozen_string_literal: true
require 'spec_helper'
require File.expand_path('ee/elastic/migrate/20241003142503_add_embedding_to_work_items.rb')
RSpec.describe AddEmbeddingToWorkItems, feature_category: :global_search do
let(:version) { 20241003142503 }
let(:migration) { described_class.new(version) }
describe 'migration', :elastic, :sidekiq_inline do
before do
skip 'migration is skipped' if migration.skip_migration?
end
include_examples 'migration adds mapping'
end
# rubocop:disable RSpec/AnyInstanceOf -- multiple instances of helper
describe '#new_mappings' do
context 'when using Elasticsearch 8 or higher' do
before do
allow_any_instance_of(Gitlab::Elastic::Helper).to receive(:matching_distribution?)
.with(:elasticsearch, min_version: '8.0.0').and_return(true)
allow_any_instance_of(Gitlab::Elastic::Helper).to receive(:matching_distribution?)
.with(:opensearch).and_return(false)
end
it 'returns the correct mapping for Elasticsearch' do
expected_mapping = {
routing: {
type: 'text'
},
embedding_0: {
type: 'dense_vector',
dims: 768,
similarity: 'cosine',
index: true
}
}
expect(migration.new_mappings).to eq(expected_mapping)
end
end
context 'when using OpenSearch' do
before do
allow_next_instance_of(Gitlab::Elastic::Helper) do |helper|
allow(helper).to receive(:matching_distribution?).with(:elasticsearch, min_version: '8.0.0').and_return(false)
allow(helper).to receive(:matching_distribution?).with(:opensearch).and_return(true)
end
allow_any_instance_of(Gitlab::Elastic::Helper).to receive(:matching_distribution?)
.with(:elasticsearch, min_version: '8.0.0').and_return(false)
allow_any_instance_of(Gitlab::Elastic::Helper).to receive(:matching_distribution?)
.with(:opensearch).and_return(true)
end
it 'returns the correct mapping for OpenSearch' do
expected_mapping = {
routing: {
type: 'text'
},
embedding_0: {
type: 'knn_vector',
dimension: 768,
method: {
name: 'hnsw',
space_type: 'cosinesimil',
parameters: {
ef_construction: 100,
m: 16
}
}
}
}
expect(migration.new_mappings).to eq(expected_mapping)
end
end
end
# rubocop:enable RSpec/AnyInstanceOf
describe 'skip_migration?' do
let(:helper) { Gitlab::Elastic::Helper.default }
before do
allow(Gitlab::Elastic::Helper).to receive(:default).and_return(helper)
allow(helper).to receive(:vectors_supported?).and_return(vectors_supported)
described_class.skip_if -> { !Gitlab::Elastic::Helper.default.vectors_supported?(:elasticsearch) }
end
context 'if vectors are supported' do
let(:vectors_supported) { true }
it 'returns false' do
expect(migration.skip_migration?).to be_falsey
end
end
context 'if vectors are not supported' do
let(:vectors_supported) { false }
it 'returns true' do
expect(migration.skip_migration?).to be_truthy
end
end
end
end
0% 加载中 .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册