Merge pull request #5418 from yandex/ngram_non_symmetric

ngramEntry function was added
This commit is contained in:
Danila Kutenin 2019-05-26 11:02:48 +03:00 committed by GitHub
commit 61a1d91d71
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 1174 additions and 26 deletions

View File

@ -32,7 +32,7 @@ namespace DB
* calculation. If the right string size is big (more than 2**15 bytes),
* the strings are not similar at all and we return 1.
*/
template <size_t N, class CodePoint, bool UTF8, bool CaseInsensitive>
template <size_t N, class CodePoint, bool UTF8, bool CaseInsensitive, bool Symmetric>
struct NgramDistanceImpl
{
using ResultType = Float32;
@ -138,6 +138,7 @@ struct NgramDistanceImpl
}
/// This is not a really true case insensitive utf8. We zero the 5-th bit of every byte.
/// And first bit of first byte if there are two bytes.
/// For ASCII it works https://catonmat.net/ascii-case-conversion-trick. For most cyrrilic letters also does.
/// For others, we don't care now. Lowering UTF is not a cheap operation.
if constexpr (CaseInsensitive)
@ -151,6 +152,7 @@ struct NgramDistanceImpl
res &= ~(1u << (5 + 2 * CHAR_BIT));
[[fallthrough]];
case 2:
res &= ~(1u);
res &= ~(1u << (5 + CHAR_BIT));
[[fallthrough]];
default:
@ -222,9 +224,10 @@ struct NgramDistanceImpl
for (; iter + N <= found; ++iter)
{
UInt16 hash = hash_functor(cp + iter);
/// For symmetric version we should add when we can't subtract to get symmetric difference.
if (static_cast<Int16>(ngram_stats[hash]) > 0)
--distance;
else
else if constexpr (Symmetric)
++distance;
if constexpr (ReuseStats)
ngram_storage[ngram_cnt] = hash;
@ -267,7 +270,8 @@ struct NgramDistanceImpl
if (data_size <= max_string_size)
{
size_t first_size = dispatchSearcher(calculateHaystackStatsAndMetric<false>, data.data(), data_size, common_stats, distance, nullptr);
res = distance * 1.f / std::max(first_size + second_size, size_t(1));
/// For !Symmetric version we should not use first_size.
res = distance * 1.f / std::max(Symmetric * first_size + second_size, size_t(1));
}
else
{
@ -326,7 +330,10 @@ struct NgramDistanceImpl
--common_stats[needle_ngram_storage[j]];
/// For now, common stats is a zero array.
res[i] = distance * 1.f / std::max(haystack_stats_size + needle_stats_size, size_t(1));
/// For !Symmetric version we should not use haystack_stats_size.
res[i] = distance * 1.f / std::max(Symmetric * haystack_stats_size + needle_stats_size, size_t(1));
}
else
{
@ -340,6 +347,71 @@ struct NgramDistanceImpl
}
}
static void constant_vector(
std::string haystack,
const ColumnString::Chars & needle_data,
const ColumnString::Offsets & needle_offsets,
PaddedPODArray<Float32> & res)
{
/// For symmetric version it is better to use vector_constant
if constexpr (Symmetric)
{
vector_constant(needle_data, needle_offsets, std::move(haystack), res);
}
else
{
const size_t haystack_size = haystack.size();
haystack.resize(haystack_size + default_padding);
/// For logic explanation see vector_vector function.
const size_t needle_offsets_size = needle_offsets.size();
size_t prev_offset = 0;
NgramStats common_stats = {};
std::unique_ptr<UInt16[]> needle_ngram_storage(new UInt16[max_string_size]);
std::unique_ptr<UInt16[]> haystack_ngram_storage(new UInt16[max_string_size]);
for (size_t i = 0; i < needle_offsets_size; ++i)
{
const char * needle = reinterpret_cast<const char *>(&needle_data[prev_offset]);
const size_t needle_size = needle_offsets[i] - prev_offset - 1;
if (needle_size <= max_string_size && haystack_size <= max_string_size)
{
const size_t needle_stats_size = dispatchSearcher(
calculateNeedleStats<true>,
needle,
needle_size,
common_stats,
needle_ngram_storage.get());
size_t distance = needle_stats_size;
dispatchSearcher(
calculateHaystackStatsAndMetric<true>,
haystack.data(),
haystack_size,
common_stats,
distance,
haystack_ngram_storage.get());
for (size_t j = 0; j < needle_stats_size; ++j)
--common_stats[needle_ngram_storage[j]];
res[i] = distance * 1.f / std::max(needle_stats_size, size_t(1));
}
else
{
res[i] = 1.f;
}
prev_offset = needle_offsets[i];
}
}
}
static void vector_constant(
const ColumnString::Chars & data,
const ColumnString::Offsets & offsets,
@ -373,7 +445,8 @@ struct NgramDistanceImpl
haystack_size, common_stats,
distance,
ngram_storage.get());
res[i] = distance * 1.f / std::max(haystack_stats_size + needle_stats_size, size_t(1));
/// For !Symmetric version we should not use haystack_stats_size.
res[i] = distance * 1.f / std::max(Symmetric * haystack_stats_size + needle_stats_size, size_t(1));
}
else
{
@ -391,7 +464,6 @@ struct NameNgramDistance
{
static constexpr auto name = "ngramDistance";
};
struct NameNgramDistanceCaseInsensitive
{
static constexpr auto name = "ngramDistanceCaseInsensitive";
@ -407,10 +479,34 @@ struct NameNgramDistanceUTF8CaseInsensitive
static constexpr auto name = "ngramDistanceCaseInsensitiveUTF8";
};
using FunctionNgramDistance = FunctionsStringSimilarity<NgramDistanceImpl<4, UInt8, false, false>, NameNgramDistance>;
using FunctionNgramDistanceCaseInsensitive = FunctionsStringSimilarity<NgramDistanceImpl<4, UInt8, false, true>, NameNgramDistanceCaseInsensitive>;
using FunctionNgramDistanceUTF8 = FunctionsStringSimilarity<NgramDistanceImpl<3, UInt32, true, false>, NameNgramDistanceUTF8>;
using FunctionNgramDistanceCaseInsensitiveUTF8 = FunctionsStringSimilarity<NgramDistanceImpl<3, UInt32, true, true>, NameNgramDistanceUTF8CaseInsensitive>;
struct NameNgramEntry
{
static constexpr auto name = "ngramEntry";
};
struct NameNgramEntryCaseInsensitive
{
static constexpr auto name = "ngramEntryCaseInsensitive";
};
struct NameNgramEntryUTF8
{
static constexpr auto name = "ngramEntryUTF8";
};
struct NameNgramEntryUTF8CaseInsensitive
{
static constexpr auto name = "ngramEntryCaseInsensitiveUTF8";
};
using FunctionNgramDistance = FunctionsStringSimilarity<NgramDistanceImpl<4, UInt8, false, false, true>, NameNgramDistance>;
using FunctionNgramDistanceCaseInsensitive = FunctionsStringSimilarity<NgramDistanceImpl<4, UInt8, false, true, true>, NameNgramDistanceCaseInsensitive>;
using FunctionNgramDistanceUTF8 = FunctionsStringSimilarity<NgramDistanceImpl<3, UInt32, true, false, true>, NameNgramDistanceUTF8>;
using FunctionNgramDistanceCaseInsensitiveUTF8 = FunctionsStringSimilarity<NgramDistanceImpl<3, UInt32, true, true, true>, NameNgramDistanceUTF8CaseInsensitive>;
using FunctionNgramEntry = FunctionsStringSimilarity<NgramDistanceImpl<4, UInt8, false, false, false>, NameNgramEntry>;
using FunctionNgramEntryCaseInsensitive = FunctionsStringSimilarity<NgramDistanceImpl<4, UInt8, false, true, false>, NameNgramEntryCaseInsensitive>;
using FunctionNgramEntryUTF8 = FunctionsStringSimilarity<NgramDistanceImpl<3, UInt32, true, false, false>, NameNgramEntryUTF8>;
using FunctionNgramEntryCaseInsensitiveUTF8 = FunctionsStringSimilarity<NgramDistanceImpl<3, UInt32, true, true, false>, NameNgramEntryUTF8CaseInsensitive>;
void registerFunctionsStringSimilarity(FunctionFactory & factory)
{
@ -418,6 +514,11 @@ void registerFunctionsStringSimilarity(FunctionFactory & factory)
factory.registerFunction<FunctionNgramDistanceCaseInsensitive>();
factory.registerFunction<FunctionNgramDistanceUTF8>();
factory.registerFunction<FunctionNgramDistanceCaseInsensitiveUTF8>();
factory.registerFunction<FunctionNgramEntry>();
factory.registerFunction<FunctionNgramEntryCaseInsensitive>();
factory.registerFunction<FunctionNgramEntryUTF8>();
factory.registerFunction<FunctionNgramEntryCaseInsensitiveUTF8>();
}
}

View File

@ -110,15 +110,15 @@ public:
}
else if (col_haystack_const && col_needle_vector)
{
const String & needle = col_haystack_const->getValue<String>();
if (needle.size() > Impl::max_string_size)
const String & haystack = col_haystack_const->getValue<String>();
if (haystack.size() > Impl::max_string_size)
{
throw Exception(
"String size of needle is too big for function " + getName() + ". Should be at most "
"String size of haystack is too big for function " + getName() + ". Should be at most "
+ std::to_string(Impl::max_string_size),
ErrorCodes::TOO_LARGE_STRING_SIZE);
}
Impl::vector_constant(col_needle_vector->getChars(), col_needle_vector->getOffsets(), needle, vec_res);
Impl::constant_vector(haystack, col_needle_vector->getChars(), col_needle_vector->getOffsets(), vec_res);
}
else
{

View File

@ -376,11 +376,11 @@ http://metrica.yandex.com/ 1000
http://metris.ru/ 1000
http://metrika.ru/ 1000
1000
привет как дела?... Херсон 676
пап привет как дела - Яндекс.Видео 733
привет как дела клип - Яндекс.Видео 739
привет братан как дела - Яндекс.Видео 750
привет 882
привет как дела?... Херсон 459
пап привет как дела - Яндекс.Видео 511
привет 529
привет как дела клип - Яндекс.Видео 565
привет братан как дела - Яндекс.Видео 583
http://metric.ru/ 1000
http://autometric.ru/ 1000
http://metrica.yandex.com/ 1000
@ -453,11 +453,11 @@ http://autometric.ru/ 1000
http://metris.ru/ 1000
http://metrika.ru/ 1000
1000
привет как дела клип - Яндекс.Видео 182
пап привет как дела - Яндекс.Видео 354
привет братан как дела - Яндекс.Видео 382
привет как дела?... Херсон 649
привет 838
привет как дела клип - Яндекс.Видео 0
пап привет как дела - Яндекс.Видео 169
привет братан как дела - Яндекс.Видео 235
привет как дела?... Херсон 544
привет 784
http://metric.ru/ 1000
http://autometric.ru/ 1000
http://metrica.yandex.com/ 1000

View File

@ -0,0 +1,855 @@
0
0
0
0
0
0
0
0
0
0
1000
1000
1000
1000
1000
0
0
0
0
0
0
0
0
0
0
500
500
500
500
500
1000
1000
1000
1000
1000
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
0
0
1000
0
0
500
1000
привет как дела?... Херсон 0
привет как дела клип - Яндекс.Видео 0
привет 0
пап привет как дела - Яндекс.Видео 0
привет братан как дела - Яндекс.Видео 0
http://metric.ru/ 0
http://autometric.ru/ 0
http://metrica.yandex.com/ 0
http://metris.ru/ 0
http://metrika.ru/ 0
0
привет как дела?... Херсон 0
привет как дела клип - Яндекс.Видео 0
привет 0
пап привет как дела - Яндекс.Видео 0
привет братан как дела - Яндекс.Видео 0
http://metric.ru/ 0
http://autometric.ru/ 0
http://metrica.yandex.com/ 0
http://metris.ru/ 0
http://metrika.ru/ 0
0
привет как дела?... Херсон 0
привет как дела клип - Яндекс.Видео 0
привет 0
пап привет как дела - Яндекс.Видео 0
привет братан как дела - Яндекс.Видео 0
http://metric.ru/ 0
http://autometric.ru/ 0
http://metrica.yandex.com/ 0
http://metris.ru/ 0
http://metrika.ru/ 0
0
привет как дела?... Херсон 0
привет как дела клип - Яндекс.Видео 0
пап привет как дела - Яндекс.Видео 0
привет братан как дела - Яндекс.Видео 77
привет 692
http://metric.ru/ 1000
http://autometric.ru/ 1000
http://metrica.yandex.com/ 1000
http://metris.ru/ 1000
http://metrika.ru/ 1000
1000
пап привет как дела - Яндекс.Видео 154
привет как дела?... Херсон 231
привет как дела клип - Яндекс.Видео 231
привет братан как дела - Яндекс.Видео 231
привет 692
http://metric.ru/ 1000
http://autometric.ru/ 1000
http://metrica.yandex.com/ 1000
http://metris.ru/ 1000
http://metrika.ru/ 1000
1000
http://metrika.ru/ 0
http://metric.ru/ 400
http://autometric.ru/ 400
http://metrica.yandex.com/ 400
http://metris.ru/ 400
привет как дела?... Херсон 1000
привет как дела клип - Яндекс.Видео 1000
привет 1000
пап привет как дела - Яндекс.Видео 1000
привет братан как дела - Яндекс.Видео 1000
1000
http://metrica.yandex.com/ 0
http://metric.ru/ 200
http://autometric.ru/ 200
http://metris.ru/ 400
http://metrika.ru/ 400
привет как дела?... Херсон 1000
привет как дела клип - Яндекс.Видео 1000
привет 1000
пап привет как дела - Яндекс.Видео 1000
привет братан как дела - Яндекс.Видео 1000
1000
http://metrika.ru/ 200
http://metric.ru/ 400
http://autometric.ru/ 400
http://metrica.yandex.com/ 400
http://metris.ru/ 400
привет как дела?... Херсон 1000
привет как дела клип - Яндекс.Видео 1000
привет 1000
пап привет как дела - Яндекс.Видео 1000
привет братан как дела - Яндекс.Видео 1000
1000
http://metric.ru/ 200
http://autometric.ru/ 200
http://metrica.yandex.com/ 200
http://metris.ru/ 400
http://metrika.ru/ 400
привет как дела?... Херсон 1000
привет как дела клип - Яндекс.Видео 1000
привет 1000
пап привет как дела - Яндекс.Видео 1000
привет братан как дела - Яндекс.Видео 1000
1000
http://metrica.yandex.com/ 0
привет как дела?... Херсон 1000
привет как дела клип - Яндекс.Видео 1000
привет 1000
пап привет как дела - Яндекс.Видео 1000
привет братан как дела - Яндекс.Видео 1000
http://metric.ru/ 1000
http://autometric.ru/ 1000
http://metris.ru/ 1000
http://metrika.ru/ 1000
1000
0
0
0
0
0
0
0
0
0
0
1000
1000
1000
1000
1000
0
0
0
0
0
0
0
0
0
0
500
500
500
500
500
1000
1000
1000
1000
1000
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
0
0
1000
429
0
500
1000
привет как дела?... Херсон 0
привет как дела клип - Яндекс.Видео 0
привет 0
пап привет как дела - Яндекс.Видео 0
привет братан как дела - Яндекс.Видео 0
http://metric.ru/ 0
http://autometric.ru/ 0
http://metrica.yandex.com/ 0
http://metris.ru/ 0
http://metrika.ru/ 0
0
привет как дела?... Херсон 0
привет как дела клип - Яндекс.Видео 0
привет 0
пап привет как дела - Яндекс.Видео 0
привет братан как дела - Яндекс.Видео 0
http://metric.ru/ 0
http://autometric.ru/ 0
http://metrica.yandex.com/ 0
http://metris.ru/ 0
http://metrika.ru/ 0
0
привет как дела?... Херсон 0
привет как дела клип - Яндекс.Видео 0
привет 0
пап привет как дела - Яндекс.Видео 0
привет братан как дела - Яндекс.Видео 0
http://metric.ru/ 0
http://autometric.ru/ 0
http://metrica.yandex.com/ 0
http://metris.ru/ 0
http://metrika.ru/ 0
0
привет как дела?... Херсон 0
привет как дела клип - Яндекс.Видео 0
пап привет как дела - Яндекс.Видео 0
привет братан как дела - Яндекс.Видео 77
привет 692
http://metric.ru/ 1000
http://autometric.ru/ 1000
http://metrica.yandex.com/ 1000
http://metris.ru/ 1000
http://metrika.ru/ 1000
1000
пап привет как дела - Яндекс.Видео 154
привет как дела?... Херсон 231
привет как дела клип - Яндекс.Видео 231
привет братан как дела - Яндекс.Видео 231
привет 692
http://metric.ru/ 1000
http://autometric.ru/ 1000
http://metrica.yandex.com/ 1000
http://metris.ru/ 1000
http://metrika.ru/ 1000
1000
http://metrika.ru/ 0
http://metric.ru/ 400
http://autometric.ru/ 400
http://metrica.yandex.com/ 400
http://metris.ru/ 400
привет как дела?... Херсон 1000
привет как дела клип - Яндекс.Видео 1000
привет 1000
пап привет как дела - Яндекс.Видео 1000
привет братан как дела - Яндекс.Видео 1000
1000
http://metrika.ru/ 0
http://metric.ru/ 400
http://autometric.ru/ 400
http://metrica.yandex.com/ 400
http://metris.ru/ 400
привет как дела?... Херсон 1000
привет как дела клип - Яндекс.Видео 1000
привет 1000
пап привет как дела - Яндекс.Видео 1000
привет братан как дела - Яндекс.Видео 1000
1000
http://metrica.yandex.com/ 0
http://metric.ru/ 200
http://autometric.ru/ 200
http://metris.ru/ 400
http://metrika.ru/ 400
привет как дела?... Херсон 1000
привет как дела клип - Яндекс.Видео 1000
привет 1000
пап привет как дела - Яндекс.Видео 1000
привет братан как дела - Яндекс.Видео 1000
1000
http://metrika.ru/ 200
http://metric.ru/ 400
http://autometric.ru/ 400
http://metrica.yandex.com/ 400
http://metris.ru/ 400
привет как дела?... Херсон 1000
привет как дела клип - Яндекс.Видео 1000
привет 1000
пап привет как дела - Яндекс.Видео 1000
привет братан как дела - Яндекс.Видео 1000
1000
http://metric.ru/ 200
http://autometric.ru/ 200
http://metrica.yandex.com/ 200
http://metris.ru/ 400
http://metrika.ru/ 400
привет как дела?... Херсон 1000
привет как дела клип - Яндекс.Видео 1000
привет 1000
пап привет как дела - Яндекс.Видео 1000
привет братан как дела - Яндекс.Видео 1000
1000
http://metrica.yandex.com/ 0
привет как дела?... Херсон 1000
привет как дела клип - Яндекс.Видео 1000
привет 1000
пап привет как дела - Яндекс.Видео 1000
привет братан как дела - Яндекс.Видео 1000
http://metric.ru/ 1000
http://autometric.ru/ 1000
http://metris.ru/ 1000
http://metrika.ru/ 1000
1000
привет как дела клип - Яндекс.Видео 0
пап привет как дела - Яндекс.Видео 182
привет братан как дела - Яндекс.Видео 212
привет как дела?... Херсон 606
привет 879
http://metric.ru/ 1000
http://autometric.ru/ 1000
http://metrica.yandex.com/ 1000
http://metris.ru/ 1000
http://metrika.ru/ 1000
1000
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
1000
1000
1000
1000
1000
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
0
0
0
0
0
0
0
привет как дела?... Херсон 0
привет как дела клип - Яндекс.Видео 0
пап привет как дела - Яндекс.Видео 0
привет братан как дела - Яндекс.Видео 40
привет 640
http://metric.ru/ 1000
http://autometric.ru/ 1000
http://metrica.yandex.com/ 1000
http://metris.ru/ 1000
http://metrika.ru/ 1000
1000
пап привет как дела - Яндекс.Видео 80
привет как дела?... Херсон 120
привет как дела клип - Яндекс.Видео 120
привет братан как дела - Яндекс.Видео 120
привет 640
http://metric.ru/ 1000
http://autometric.ru/ 1000
http://metrica.yandex.com/ 1000
http://metris.ru/ 1000
http://metrika.ru/ 1000
1000
http://metrika.ru/ 0
http://metric.ru/ 500
http://autometric.ru/ 500
http://metrica.yandex.com/ 500
http://metris.ru/ 500
привет как дела?... Херсон 1000
привет как дела клип - Яндекс.Видео 1000
привет 1000
пап привет как дела - Яндекс.Видео 1000
привет братан как дела - Яндекс.Видео 1000
1000
http://metrica.yandex.com/ 0
http://metric.ru/ 250
http://autometric.ru/ 250
http://metris.ru/ 500
http://metrika.ru/ 500
привет как дела?... Херсон 1000
привет как дела клип - Яндекс.Видео 1000
привет 1000
пап привет как дела - Яндекс.Видео 1000
привет братан как дела - Яндекс.Видео 1000
1000
http://metrika.ru/ 250
http://metric.ru/ 500
http://autometric.ru/ 500
http://metrica.yandex.com/ 500
http://metris.ru/ 500
привет как дела?... Херсон 1000
привет как дела клип - Яндекс.Видео 1000
привет 1000
пап привет как дела - Яндекс.Видео 1000
привет братан как дела - Яндекс.Видео 1000
1000
http://metric.ru/ 250
http://autometric.ru/ 250
http://metrica.yandex.com/ 250
http://metris.ru/ 500
http://metrika.ru/ 500
привет как дела?... Херсон 1000
привет как дела клип - Яндекс.Видео 1000
привет 1000
пап привет как дела - Яндекс.Видео 1000
привет братан как дела - Яндекс.Видео 1000
1000
http://metrica.yandex.com/ 0
привет как дела?... Херсон 1000
привет как дела клип - Яндекс.Видео 1000
привет 1000
пап привет как дела - Яндекс.Видео 1000
привет братан как дела - Яндекс.Видео 1000
http://metric.ru/ 1000
http://autometric.ru/ 1000
http://metris.ru/ 1000
http://metrika.ru/ 1000
1000
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
1000
1000
1000
1000
1000
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
0
0
0
0
0
0
0
привет как дела?... Херсон 880
привет как дела клип - Яндекс.Видео 880
пап привет как дела - Яндекс.Видео 880
привет братан как дела - Яндекс.Видео 920
привет 1000
http://metric.ru/ 1000
http://autometric.ru/ 1000
http://metrica.yandex.com/ 1000
http://metris.ru/ 1000
http://metrika.ru/ 1000
1000
привет как дела?... Херсон 560
привет как дела клип - Яндекс.Видео 560
пап привет как дела - Яндекс.Видео 560
привет братан как дела - Яндекс.Видео 560
привет 1000
http://metric.ru/ 1000
http://autometric.ru/ 1000
http://metrica.yandex.com/ 1000
http://metris.ru/ 1000
http://metrika.ru/ 1000
1000
http://metrika.ru/ 0
http://metric.ru/ 500
http://autometric.ru/ 500
http://metrica.yandex.com/ 500
http://metris.ru/ 500
привет как дела?... Херсон 1000
привет как дела клип - Яндекс.Видео 1000
привет 1000
пап привет как дела - Яндекс.Видео 1000
привет братан как дела - Яндекс.Видео 1000
1000
http://metrika.ru/ 0
http://metric.ru/ 500
http://autometric.ru/ 500
http://metrica.yandex.com/ 500
http://metris.ru/ 500
привет как дела?... Херсон 1000
привет как дела клип - Яндекс.Видео 1000
привет 1000
пап привет как дела - Яндекс.Видео 1000
привет братан как дела - Яндекс.Видео 1000
1000
http://metrica.yandex.com/ 0
http://metric.ru/ 250
http://autometric.ru/ 250
http://metris.ru/ 500
http://metrika.ru/ 500
привет как дела?... Херсон 1000
привет как дела клип - Яндекс.Видео 1000
привет 1000
пап привет как дела - Яндекс.Видео 1000
привет братан как дела - Яндекс.Видео 1000
1000
http://metrika.ru/ 250
http://metric.ru/ 500
http://autometric.ru/ 500
http://metrica.yandex.com/ 500
http://metris.ru/ 500
привет как дела?... Херсон 1000
привет как дела клип - Яндекс.Видео 1000
привет 1000
пап привет как дела - Яндекс.Видео 1000
привет братан как дела - Яндекс.Видео 1000
1000
http://metric.ru/ 250
http://autometric.ru/ 250
http://metrica.yandex.com/ 250
http://metris.ru/ 500
http://metrika.ru/ 500
привет как дела?... Херсон 1000
привет как дела клип - Яндекс.Видео 1000
привет 1000
пап привет как дела - Яндекс.Видео 1000
привет братан как дела - Яндекс.Видео 1000
1000
http://metrica.yandex.com/ 0
привет как дела?... Херсон 1000
привет как дела клип - Яндекс.Видео 1000
привет 1000
пап привет как дела - Яндекс.Видео 1000
привет братан как дела - Яндекс.Видео 1000
http://metric.ru/ 1000
http://autometric.ru/ 1000
http://metris.ru/ 1000
http://metrika.ru/ 1000
1000

View File

@ -0,0 +1,180 @@
select round(1000 * ngramEntryUTF8(materialize(''), '')) from system.numbers limit 5;
select round(1000 * ngramEntryUTF8(materialize('абв'), '')) from system.numbers limit 5;
select round(1000 * ngramEntryUTF8(materialize(''), 'абв')) from system.numbers limit 5;
select round(1000 * ngramEntryUTF8(materialize('абвгдеёжз'), 'абвгдеёжз')) from system.numbers limit 5;
select round(1000 * ngramEntryUTF8(materialize('абвгдеёжз'), 'абвгдеёж')) from system.numbers limit 5;
select round(1000 * ngramEntryUTF8(materialize('абвгдеёжз'), 'гдеёзд')) from system.numbers limit 5;
select round(1000 * ngramEntryUTF8(materialize('абвгдеёжз'), 'ёёёёёёёё')) from system.numbers limit 5;
select round(1000 * ngramEntryUTF8(materialize(''), materialize('')))=round(1000 * ngramEntryUTF8(materialize(''), '')) from system.numbers limit 5;
select round(1000 * ngramEntryUTF8(materialize('абв'), materialize('')))=round(1000 * ngramEntryUTF8(materialize('абв'), '')) from system.numbers limit 5;
select round(1000 * ngramEntryUTF8(materialize(''), materialize('абв')))=round(1000 * ngramEntryUTF8(materialize(''), 'абв')) from system.numbers limit 5;
select round(1000 * ngramEntryUTF8(materialize('абвгдеёжз'), materialize('абвгдеёжз')))=round(1000 * ngramEntryUTF8(materialize('абвгдеёжз'), 'абвгдеёжз')) from system.numbers limit 5;
select round(1000 * ngramEntryUTF8(materialize('абвгдеёжз'), materialize('абвгдеёж')))=round(1000 * ngramEntryUTF8(materialize('абвгдеёжз'), 'абвгдеёж')) from system.numbers limit 5;
select round(1000 * ngramEntryUTF8(materialize('абвгдеёжз'), materialize('гдеёзд')))=round(1000 * ngramEntryUTF8(materialize('абвгдеёжз'), 'гдеёзд')) from system.numbers limit 5;
select round(1000 * ngramEntryUTF8(materialize('абвгдеёжз'), materialize('ёёёёёёёё')))=round(1000 * ngramEntryUTF8(materialize('абвгдеёжз'), 'ёёёёёёёё')) from system.numbers limit 5;
select round(1000 * ngramEntryUTF8('', materialize('')))=round(1000 * ngramEntryUTF8(materialize(''), '')) from system.numbers limit 5;
select round(1000 * ngramEntryUTF8('абв', materialize('')))=round(1000 * ngramEntryUTF8(materialize('абв'), '')) from system.numbers limit 5;
select round(1000 * ngramEntryUTF8('', materialize('абв')))=round(1000 * ngramEntryUTF8(materialize(''), 'абв')) from system.numbers limit 5;
select round(1000 * ngramEntryUTF8('абвгдеёжз', materialize('абвгдеёжз')))=round(1000 * ngramEntryUTF8(materialize('абвгдеёжз'), 'абвгдеёжз')) from system.numbers limit 5;
select round(1000 * ngramEntryUTF8('абвгдеёжз', materialize('абвгдеёж')))=round(1000 * ngramEntryUTF8(materialize('абвгдеёжз'), 'абвгдеёж')) from system.numbers limit 5;
select round(1000 * ngramEntryUTF8('абвгдеёжз', materialize('гдеёзд')))=round(1000 * ngramEntryUTF8(materialize('абвгдеёжз'), 'гдеёзд')) from system.numbers limit 5;
select round(1000 * ngramEntryUTF8('абвгдеёжз', materialize('ёёёёёёёё')))=round(1000 * ngramEntryUTF8(materialize('абвгдеёжз'), 'ёёёёёёёё')) from system.numbers limit 5;
select round(1000 * ngramEntryUTF8('', ''));
select round(1000 * ngramEntryUTF8('абв', ''));
select round(1000 * ngramEntryUTF8('', 'абв'));
select round(1000 * ngramEntryUTF8('абвгдеёжз', 'абвгдеёжз'));
select round(1000 * ngramEntryUTF8('абвгдеёжз', 'абвгдеёж'));
select round(1000 * ngramEntryUTF8('абвгдеёжз', 'гдеёзд'));
select round(1000 * ngramEntryUTF8('абвгдеёжз', 'ёёёёёёёё'));
drop table if exists test_entry_distance;
create table test_entry_distance (Title String) engine = Memory;
insert into test_entry_distance values ('привет как дела?... Херсон'), ('привет как дела клип - Яндекс.Видео'), ('привет'), ('пап привет как дела - Яндекс.Видео'), ('привет братан как дела - Яндекс.Видео'), ('http://metric.ru/'), ('http://autometric.ru/'), ('http://metrica.yandex.com/'), ('http://metris.ru/'), ('http://metrika.ru/'), ('');
SELECT Title, round(1000 * distance) FROM test_entry_distance ORDER BY ngramEntryUTF8(Title, Title) as distance;
SELECT Title, round(1000 * distance) FROM test_entry_distance ORDER BY ngramEntryUTF8(Title, extract(Title, 'как дела')) as distance;
SELECT Title, round(1000 * distance) FROM test_entry_distance ORDER BY ngramEntryUTF8(Title, extract(Title, 'metr')) as distance;
SELECT Title, round(1000 * distance) FROM test_entry_distance ORDER BY ngramEntryUTF8(Title, 'привет как дела') as distance;
SELECT Title, round(1000 * distance) FROM test_entry_distance ORDER BY ngramEntryUTF8(Title, 'как привет дела') as distance;
SELECT Title, round(1000 * distance) FROM test_entry_distance ORDER BY ngramEntryUTF8(Title, 'metrika') as distance;
SELECT Title, round(1000 * distance) FROM test_entry_distance ORDER BY ngramEntryUTF8(Title, 'metrica') as distance;
SELECT Title, round(1000 * distance) FROM test_entry_distance ORDER BY ngramEntryUTF8(Title, 'metriks') as distance;
SELECT Title, round(1000 * distance) FROM test_entry_distance ORDER BY ngramEntryUTF8(Title, 'metrics') as distance;
SELECT Title, round(1000 * distance) FROM test_entry_distance ORDER BY ngramEntryUTF8(Title, 'yandex') as distance;
select round(1000 * ngramEntryCaseInsensitiveUTF8(materialize(''), '')) from system.numbers limit 5;
select round(1000 * ngramEntryCaseInsensitiveUTF8(materialize('абв'), '')) from system.numbers limit 5;
select round(1000 * ngramEntryCaseInsensitiveUTF8(materialize(''), 'абв')) from system.numbers limit 5;
select round(1000 * ngramEntryCaseInsensitiveUTF8(materialize('абвГДЕёжз'), 'АбвгдЕёжз')) from system.numbers limit 5;
select round(1000 * ngramEntryCaseInsensitiveUTF8(materialize('аБВГдеёЖз'), 'АбвГдеёж')) from system.numbers limit 5;
select round(1000 * ngramEntryCaseInsensitiveUTF8(materialize('абвгдеёжз'), 'гдеёЗД')) from system.numbers limit 5;
select round(1000 * ngramEntryCaseInsensitiveUTF8(materialize('абвгдеёжз'), 'ЁЁЁЁЁЁЁЁ')) from system.numbers limit 5;
select round(1000 * ngramEntryCaseInsensitiveUTF8(materialize(''),materialize(''))) = round(1000 * ngramEntryCaseInsensitiveUTF8(materialize(''), '')) from system.numbers limit 5;
select round(1000 * ngramEntryCaseInsensitiveUTF8(materialize('абв'),materialize(''))) = round(1000 * ngramEntryCaseInsensitiveUTF8(materialize('абв'), '')) from system.numbers limit 5;
select round(1000 * ngramEntryCaseInsensitiveUTF8(materialize(''), materialize('абв'))) = round(1000 * ngramEntryCaseInsensitiveUTF8(materialize(''), 'абв')) from system.numbers limit 5;
select round(1000 * ngramEntryCaseInsensitiveUTF8(materialize('абвГДЕёжз'), materialize('АбвгдЕёжз'))) = round(1000 * ngramEntryCaseInsensitiveUTF8(materialize('абвГДЕёжз'), 'АбвгдЕёжз')) from system.numbers limit 5;
select round(1000 * ngramEntryCaseInsensitiveUTF8(materialize('аБВГдеёЖз'), materialize('АбвГдеёж'))) = round(1000 * ngramEntryCaseInsensitiveUTF8(materialize('аБВГдеёЖз'), 'АбвГдеёж')) from system.numbers limit 5;
select round(1000 * ngramEntryCaseInsensitiveUTF8(materialize('абвгдеёжз'), materialize('гдеёЗД'))) = round(1000 * ngramEntryCaseInsensitiveUTF8(materialize('абвгдеёжз'), 'гдеёЗД')) from system.numbers limit 5;
select round(1000 * ngramEntryCaseInsensitiveUTF8(materialize('абвгдеёжз'), materialize('ЁЁЁЁЁЁЁЁ'))) = round(1000 * ngramEntryCaseInsensitiveUTF8(materialize('абвгдеёжз'), 'ЁЁЁЁЁЁЁЁ')) from system.numbers limit 5;
select round(1000 * ngramEntryCaseInsensitiveUTF8('', materialize(''))) = round(1000 * ngramEntryCaseInsensitiveUTF8(materialize(''), '')) from system.numbers limit 5;
select round(1000 * ngramEntryCaseInsensitiveUTF8('абв',materialize(''))) = round(1000 * ngramEntryCaseInsensitiveUTF8(materialize('абв'), '')) from system.numbers limit 5;
select round(1000 * ngramEntryCaseInsensitiveUTF8('', materialize('абв'))) = round(1000 * ngramEntryCaseInsensitiveUTF8(materialize(''), 'абв')) from system.numbers limit 5;
select round(1000 * ngramEntryCaseInsensitiveUTF8('абвГДЕёжз', materialize('АбвгдЕёжз'))) = round(1000 * ngramEntryCaseInsensitiveUTF8(materialize('абвГДЕёжз'), 'АбвгдЕёжз')) from system.numbers limit 5;
select round(1000 * ngramEntryCaseInsensitiveUTF8('аБВГдеёЖз', materialize('АбвГдеёж'))) = round(1000 * ngramEntryCaseInsensitiveUTF8(materialize('аБВГдеёЖз'), 'АбвГдеёж')) from system.numbers limit 5;
select round(1000 * ngramEntryCaseInsensitiveUTF8('абвгдеёжз', materialize('гдеёЗД'))) = round(1000 * ngramEntryCaseInsensitiveUTF8(materialize('абвгдеёжз'), 'гдеёЗД')) from system.numbers limit 5;
select round(1000 * ngramEntryCaseInsensitiveUTF8('абвгдеёжз', materialize('ЁЁЁЁЁЁЁЁ'))) = round(1000 * ngramEntryCaseInsensitiveUTF8(materialize('абвгдеёжз'), 'ЁЁЁЁЁЁЁЁ')) from system.numbers limit 5;
select round(1000 * ngramEntryCaseInsensitiveUTF8('', ''));
select round(1000 * ngramEntryCaseInsensitiveUTF8('абв', ''));
select round(1000 * ngramEntryCaseInsensitiveUTF8('', 'абв'));
select round(1000 * ngramEntryCaseInsensitiveUTF8('абвГДЕёжз', 'АбвгдЕЁжз'));
select round(1000 * ngramEntryCaseInsensitiveUTF8('аБВГдеёЖз', 'АбвГдеёж'));
select round(1000 * ngramEntryCaseInsensitiveUTF8('абвгдеёжз', 'гдеёЗД'));
select round(1000 * ngramEntryCaseInsensitiveUTF8('АБВГДеёжз', 'ЁЁЁЁЁЁЁЁ'));
SELECT Title, round(1000 * distance) FROM test_entry_distance ORDER BY ngramEntryCaseInsensitiveUTF8(Title, Title) as distance;
SELECT Title, round(1000 * distance) FROM test_entry_distance ORDER BY ngramEntryCaseInsensitiveUTF8(Title, extract(Title, 'как дела')) as distance;
SELECT Title, round(1000 * distance) FROM test_entry_distance ORDER BY ngramEntryCaseInsensitiveUTF8(Title, extract(Title, 'metr')) as distance;
SELECT Title, round(1000 * distance) FROM test_entry_distance ORDER BY ngramEntryCaseInsensitiveUTF8(Title, 'ПрИвЕт кАК ДЕЛа') as distance;
SELECT Title, round(1000 * distance) FROM test_entry_distance ORDER BY ngramEntryCaseInsensitiveUTF8(Title, 'как ПРИВЕТ дела') as distance;
SELECT Title, round(1000 * distance) FROM test_entry_distance ORDER BY ngramEntryCaseInsensitiveUTF8(Title, 'metrika') as distance;
SELECT Title, round(1000 * distance) FROM test_entry_distance ORDER BY ngramEntryCaseInsensitiveUTF8(Title, 'Metrika') as distance;
SELECT Title, round(1000 * distance) FROM test_entry_distance ORDER BY ngramEntryCaseInsensitiveUTF8(Title, 'mEtrica') as distance;
SELECT Title, round(1000 * distance) FROM test_entry_distance ORDER BY ngramEntryCaseInsensitiveUTF8(Title, 'metriKS') as distance;
SELECT Title, round(1000 * distance) FROM test_entry_distance ORDER BY ngramEntryCaseInsensitiveUTF8(Title, 'metrics') as distance;
SELECT Title, round(1000 * distance) FROM test_entry_distance ORDER BY ngramEntryCaseInsensitiveUTF8(Title, 'YanDEX') as distance;
SELECT Title, round(1000 * distance) FROM test_entry_distance ORDER BY ngramEntryCaseInsensitiveUTF8(Title, 'приВЕТ КАк ДеЛа КлИп - яндеКс.видео') as distance;
select round(1000 * ngramEntry(materialize(''), '')) from system.numbers limit 5;
select round(1000 * ngramEntry(materialize('abc'), '')) from system.numbers limit 5;
select round(1000 * ngramEntry(materialize(''), 'abc')) from system.numbers limit 5;
select round(1000 * ngramEntry(materialize('abcdefgh'), 'abcdefgh')) from system.numbers limit 5;
select round(1000 * ngramEntry(materialize('abcdefgh'), 'abcdefg')) from system.numbers limit 5;
select round(1000 * ngramEntry(materialize('abcdefgh'), 'defgh')) from system.numbers limit 5;
select round(1000 * ngramEntry(materialize('abcdefgh'), 'aaaaaaaa')) from system.numbers limit 5;
select round(1000 * ngramEntry(materialize(''),materialize('')))=round(1000 * ngramEntry(materialize(''), '')) from system.numbers limit 5;
select round(1000 * ngramEntry(materialize('abc'),materialize('')))=round(1000 * ngramEntry(materialize('abc'), '')) from system.numbers limit 5;
select round(1000 * ngramEntry(materialize(''), materialize('abc')))=round(1000 * ngramEntry(materialize(''), 'abc')) from system.numbers limit 5;
select round(1000 * ngramEntry(materialize('abcdefgh'), materialize('abcdefgh')))=round(1000 * ngramEntry(materialize('abcdefgh'), 'abcdefgh')) from system.numbers limit 5;
select round(1000 * ngramEntry(materialize('abcdefgh'), materialize('abcdefg')))=round(1000 * ngramEntry(materialize('abcdefgh'), 'abcdefg')) from system.numbers limit 5;
select round(1000 * ngramEntry(materialize('abcdefgh'), materialize('defgh')))=round(1000 * ngramEntry(materialize('abcdefgh'), 'defgh')) from system.numbers limit 5;
select round(1000 * ngramEntry(materialize('abcdefgh'), materialize('aaaaaaaa')))=round(1000 * ngramEntry(materialize('abcdefgh'), 'aaaaaaaa')) from system.numbers limit 5;
select round(1000 * ngramEntry('',materialize('')))=round(1000 * ngramEntry(materialize(''), '')) from system.numbers limit 5;
select round(1000 * ngramEntry('abc', materialize('')))=round(1000 * ngramEntry(materialize('abc'), '')) from system.numbers limit 5;
select round(1000 * ngramEntry('', materialize('abc')))=round(1000 * ngramEntry(materialize(''), 'abc')) from system.numbers limit 5;
select round(1000 * ngramEntry('abcdefgh', materialize('abcdefgh')))=round(1000 * ngramEntry(materialize('abcdefgh'), 'abcdefgh')) from system.numbers limit 5;
select round(1000 * ngramEntry('abcdefgh', materialize('abcdefg')))=round(1000 * ngramEntry(materialize('abcdefgh'), 'abcdefg')) from system.numbers limit 5;
select round(1000 * ngramEntry('abcdefgh', materialize('defgh')))=round(1000 * ngramEntry(materialize('abcdefgh'), 'defgh')) from system.numbers limit 5;
select round(1000 * ngramEntry('abcdefgh', materialize('aaaaaaaa')))=round(1000 * ngramEntry(materialize('abcdefgh'), 'aaaaaaaa')) from system.numbers limit 5;
select round(1000 * ngramEntry('', ''));
select round(1000 * ngramEntry('abc', ''));
select round(1000 * ngramEntry('', 'abc'));
select round(1000 * ngramEntry('abcdefgh', 'abcdefgh'));
select round(1000 * ngramEntry('abcdefgh', 'abcdefg'));
select round(1000 * ngramEntry('abcdefgh', 'defgh'));
select round(1000 * ngramEntry('abcdefghaaaaaaaaaa', 'aaaaaaaa'));
SELECT Title, round(1000 * distance) FROM test_entry_distance ORDER BY ngramEntry(Title, 'привет как дела') as distance;
SELECT Title, round(1000 * distance) FROM test_entry_distance ORDER BY ngramEntry(Title, 'как привет дела') as distance;
SELECT Title, round(1000 * distance) FROM test_entry_distance ORDER BY ngramEntry(Title, 'metrika') as distance;
SELECT Title, round(1000 * distance) FROM test_entry_distance ORDER BY ngramEntry(Title, 'metrica') as distance;
SELECT Title, round(1000 * distance) FROM test_entry_distance ORDER BY ngramEntry(Title, 'metriks') as distance;
SELECT Title, round(1000 * distance) FROM test_entry_distance ORDER BY ngramEntry(Title, 'metrics') as distance;
SELECT Title, round(1000 * distance) FROM test_entry_distance ORDER BY ngramEntry(Title, 'yandex') as distance;
select round(1000 * ngramEntryCaseInsensitive(materialize(''), '')) from system.numbers limit 5;
select round(1000 * ngramEntryCaseInsensitive(materialize('abc'), '')) from system.numbers limit 5;
select round(1000 * ngramEntryCaseInsensitive(materialize(''), 'abc')) from system.numbers limit 5;
select round(1000 * ngramEntryCaseInsensitive(materialize('abCdefgH'), 'Abcdefgh')) from system.numbers limit 5;
select round(1000 * ngramEntryCaseInsensitive(materialize('abcdefgh'), 'abcdeFG')) from system.numbers limit 5;
select round(1000 * ngramEntryCaseInsensitive(materialize('AAAAbcdefgh'), 'defgh')) from system.numbers limit 5;
select round(1000 * ngramEntryCaseInsensitive(materialize('ABCdefgH'), 'aaaaaaaa')) from system.numbers limit 5;
select round(1000 * ngramEntryCaseInsensitive(materialize(''), materialize('')))=round(1000 * ngramEntryCaseInsensitive(materialize(''), '')) from system.numbers limit 5;
select round(1000 * ngramEntryCaseInsensitive(materialize('abc'), materialize('')))=round(1000 * ngramEntryCaseInsensitive(materialize('abc'), '')) from system.numbers limit 5;
select round(1000 * ngramEntryCaseInsensitive(materialize(''), materialize('abc')))=round(1000 * ngramEntryCaseInsensitive(materialize(''), 'abc')) from system.numbers limit 5;
select round(1000 * ngramEntryCaseInsensitive(materialize('abCdefgH'), materialize('Abcdefgh')))=round(1000 * ngramEntryCaseInsensitive(materialize('abCdefgH'), 'Abcdefgh')) from system.numbers limit 5;
select round(1000 * ngramEntryCaseInsensitive(materialize('abcdefgh'), materialize('abcdeFG')))=round(1000 * ngramEntryCaseInsensitive(materialize('abcdefgh'), 'abcdeFG')) from system.numbers limit 5;
select round(1000 * ngramEntryCaseInsensitive(materialize('AAAAbcdefgh'), materialize('defgh')))=round(1000 * ngramEntryCaseInsensitive(materialize('AAAAbcdefgh'), 'defgh')) from system.numbers limit 5;
select round(1000 * ngramEntryCaseInsensitive(materialize('ABCdefgH'), materialize('aaaaaaaa')))=round(1000 * ngramEntryCaseInsensitive(materialize('ABCdefgH'), 'aaaaaaaa')) from system.numbers limit 5;
select round(1000 * ngramEntryCaseInsensitive('', materialize('')))=round(1000 * ngramEntryCaseInsensitive(materialize(''), '')) from system.numbers limit 5;
select round(1000 * ngramEntryCaseInsensitive('abc', materialize('')))=round(1000 * ngramEntryCaseInsensitive(materialize('abc'), '')) from system.numbers limit 5;
select round(1000 * ngramEntryCaseInsensitive('', materialize('abc')))=round(1000 * ngramEntryCaseInsensitive(materialize(''), 'abc')) from system.numbers limit 5;
select round(1000 * ngramEntryCaseInsensitive('abCdefgH', materialize('Abcdefgh')))=round(1000 * ngramEntryCaseInsensitive(materialize('abCdefgH'), 'Abcdefgh')) from system.numbers limit 5;
select round(1000 * ngramEntryCaseInsensitive('abcdefgh', materialize('abcdeFG')))=round(1000 * ngramEntryCaseInsensitive(materialize('abcdefgh'), 'abcdeFG')) from system.numbers limit 5;
select round(1000 * ngramEntryCaseInsensitive('AAAAbcdefgh', materialize('defgh')))=round(1000 * ngramEntryCaseInsensitive(materialize('AAAAbcdefgh'), 'defgh')) from system.numbers limit 5;
select round(1000 * ngramEntryCaseInsensitive('ABCdefgH', materialize('aaaaaaaa')))=round(1000 * ngramEntryCaseInsensitive(materialize('ABCdefgH'), 'aaaaaaaa')) from system.numbers limit 5;
select round(1000 * ngramEntryCaseInsensitive('', ''));
select round(1000 * ngramEntryCaseInsensitive('abc', ''));
select round(1000 * ngramEntryCaseInsensitive('', 'abc'));
select round(1000 * ngramEntryCaseInsensitive('abCdefgH', 'Abcdefgh'));
select round(1000 * ngramEntryCaseInsensitive('abcdefgh', 'abcdeFG'));
select round(1000 * ngramEntryCaseInsensitive('AAAAbcdefgh', 'defgh'));
select round(1000 * ngramEntryCaseInsensitive('ABCdefgHaAaaaAaaaAA', 'aaaaaaaa'));
SELECT Title, round(1000 * distance) FROM test_entry_distance ORDER BY ngramEntryCaseInsensitive(Title, 'ПрИвЕт кАК ДЕЛа') as distance;
SELECT Title, round(1000 * distance) FROM test_entry_distance ORDER BY ngramEntryCaseInsensitive(Title, 'как ПРИВЕТ дела') as distance;
SELECT Title, round(1000 * distance) FROM test_entry_distance ORDER BY ngramEntryCaseInsensitive(Title, 'metrika') as distance;
SELECT Title, round(1000 * distance) FROM test_entry_distance ORDER BY ngramEntryCaseInsensitive(Title, 'Metrika') as distance;
SELECT Title, round(1000 * distance) FROM test_entry_distance ORDER BY ngramEntryCaseInsensitive(Title, 'mEtrica') as distance;
SELECT Title, round(1000 * distance) FROM test_entry_distance ORDER BY ngramEntryCaseInsensitive(Title, 'metriKS') as distance;
SELECT Title, round(1000 * distance) FROM test_entry_distance ORDER BY ngramEntryCaseInsensitive(Title, 'metrics') as distance;
SELECT Title, round(1000 * distance) FROM test_entry_distance ORDER BY ngramEntryCaseInsensitive(Title, 'YanDEX') as distance;
drop table if exists test_entry_distance;

View File

@ -106,7 +106,12 @@ Calculates the 4-gram distance between `haystack` and `needle`: counts the symme
For case-insensitive search or/and in UTF-8 format use functions `ngramDistanceCaseInsensitive, ngramDistanceUTF8, ngramDistanceCaseInsensitiveUTF8`.
**Note: For UTF-8 case we use 3-gram distance. All these are not perfectly fair n-gram distances. We use 2-byte hashes to hash n-grams and then calculate the symmetric difference between these hash tables -- collisions may occur. With UTF-8 case-insensitive format we do not use fair `tolower` function -- we zero the 5-th bit (starting from zero) of each codepoint byte -- this works for Latin and mostly for all Cyrillic letters.**
## ngramEntry(haystack, needle)
Same as `ngramDistance` but calculates the non-symmetric difference between `needle` and `haystack` -- the number of n-grams from needle minus the common number of n-grams normalized by the number of `needle` n-grams. Can be useful for fuzzy string search.
For case-insensitive search or/and in UTF-8 format use functions `ngramEntryCaseInsensitive, ngramEntryUTF8, ngramEntryCaseInsensitiveUTF8`.
**Note: For UTF-8 case we use 3-gram distance. All these are not perfectly fair n-gram distances. We use 2-byte hashes to hash n-grams and then calculate the (non-)symmetric difference between these hash tables -- collisions may occur. With UTF-8 case-insensitive format we do not use fair `tolower` function -- we zero the 5-th bit (starting from zero) of each codepoint byte and first bit of zeroth byte if bytes more than one -- this works for Latin and mostly for all Cyrillic letters.**
[Original article](https://clickhouse.yandex/docs/en/query_language/functions/string_search_functions/) <!--hide-->

View File

@ -95,6 +95,13 @@
Для поиска без учета регистра и/или в формате UTF-8 используйте функции `ngramDistanceCaseInsensitive, ngramDistanceUTF8, ngramDistanceCaseInsensitiveUTF8`.
**Примечание: для случая UTF-8 мы используем триграммное расстояние. Вычисление n-граммного расстояния не совсем честное. Мы используем 2-х байтные хэши для хэширования n-грамм, а затем вычисляем симметричную разность между хэш таблицами -- могут возникнуть коллизии. В формате UTF-8 без учета регистра мы не используем честную функцию `tolower` -- мы обнуляем 5-й бит (нумерация с нуля) каждого байта кодовой точки -- это работает для латиницы и почти для всех кириллических букв.**
## ngramEntry(haystack, needle)
То же, что и `ngramDistance`, но вычисляет несимметричную разность между `needle` и `haystack` -- количество n-грамм из `needle` минус количество общих n-грамм, нормированное на количество n-грамм из `needle`. Может быть использовано для приближенного поиска.
Для поиска без учета регистра и/или в формате UTF-8 используйте функции `ngramEntryCaseInsensitive, ngramEntryUTF8, ngramEntryCaseInsensitiveUTF8`.
**Примечание: для случая UTF-8 мы используем триграммное расстояние. Вычисление n-граммного расстояния не совсем честное. Мы используем 2-х байтные хэши для хэширования n-грамм, а затем вычисляем (не)симметрическую разность между хэш таблицами -- могут возникнуть коллизии. В формате UTF-8 без учета регистра мы не используем честную функцию `tolower` -- мы обнуляем 5-й бит (нумерация с нуля) каждого байта кодовой точки, а также первый бит нулевого байта, если байтов больше 1 -- это работает для латиницы и почти для всех кириллических букв.**
[Оригинальная статья](https://clickhouse.yandex/docs/ru/query_language/functions/string_search_functions/) <!--hide-->