🦔

ArangoDB3.9.0-alpha.1入れてみた

2021/12/16に公開

ArangoDB3.9Alpha1がリリースされました

https://www.arangodb.com/download-technical-preview/?utm_content=190520694&utm_medium=social&utm_source=twitter&hss_channel=tw-398200139

インストール(DockerDesktop)

Dockerfile

FROM arangodb/arangodb-preview:3.9.0-alpha.1

docker-compose.yml

version: '3'

services:
  hello-arangodb:
    build: .
    ports:
      - '8529:8529'
    environment:
      ARANGO_ROOT_PASSWORD: "rootアカウントのパスワード指定"
      ARANGODB_OVERRIDE_DETECTED_TOTAL_MEMORY: "2G"
#      ARANGO_ROOT_PASSWORD_FILE: 
#      ARANGO_NO_AUTH: 0
#      ARANGO_RANDOM_ROOT_PASSWORD: 0
    volumes:
      - ./arangodb3:/var/lib/arangodb3
      - ./arangodb3-apps:/var/lib/arangodb3-apps

出来上がり

3.9になってる!
3.9


変更点

https://www.arangodb.com/docs/3.9/release-notes-new-features39.html#prune-variable


Decay Functions

DECAY_EXP()
DECAY_LINEAR()
DECAY_GAUSS()

例見ても何やってるのかさっぱりわからんので一番簡単そうなDECAY_LINEARを調べた
arangodb-3.9.0-alpha.1\arangod\Aql\Functions.cpp

DECAY_LINEAR

AqlValue Functions::DecayLinear(arangodb::aql::ExpressionContext* expressionContext,
                                AstNode const& node,
                                VPackFunctionParameters const& parameters) {

  auto linearDecayFactory = [](const double origin,
                               const double scale,
                               const double offset,
                               const double decay) {
    const double s = scale / (1.0 - decay);
    return [=](double arg) {
      double max = std::max(0.0, std::fabs(arg - origin) - offset);
      double val = std::max((s - max) / s, 0.0);
      return val;
    };
  };

  return decayFuncImpl(expressionContext, node, parameters, linearDecayFactory);
}

DECAY_LINEAR(5, 0, 10, 0, 0.2) // 0.6だと
origin0
scale10
offset0
decay0.2
ラムダ関数のarg5
const double s = scale / (1.0 - decay);s12.5
double max = std::max(0.0, std::fabs(arg - origin) - offset);max5
double val = std::max((s - max) / s, 0.0);val0.6となる
…何に使うのかよくわからないけどなにかに使えるんだろう…

DECAY_EXP

AqlValue Functions::DecayExp(arangodb::aql::ExpressionContext* expressionContext,
                             AstNode const& node,
                             VPackFunctionParameters const& parameters) {

  auto expDecayFactory = [](const double origin,
                            const double scale,
                            const double offset,
                            const double decay) {
    const double lambda = std::log(decay) / scale;
    return [=](double arg) {
      double numerator = lambda * std::max(0.0, std::abs(arg - origin) - offset);
      double val = std::exp(numerator);
      return val;
    };
  };

  return decayFuncImpl(expressionContext, node, parameters, expDecayFactory);
}

自然対数を使った減衰計算なんだろう…

DECAY_GAUSS

AqlValue Functions::DecayGauss(arangodb::aql::ExpressionContext* expressionContext,
                               AstNode const& node,
                               VPackFunctionParameters const& parameters) {

  auto gaussDecayFactory = [](const double origin,
                              const double scale,
                              const double offset,
                              const double decay) {
    const double sigmaSqr = - (scale * scale) / (2 * std::log(decay));
    return [=](double arg) {
      double max = std::max(0.0, std::fabs(arg - origin) - offset);
      double numerator = max * max;
      double val = std::exp(- numerator / (2 * sigmaSqr));
      return val;
    };
  };

  return decayFuncImpl(expressionContext, node, parameters, gaussDecayFactory);
}

ガウス関数を使った減衰計算なんだろう…


Vector Functions

COSINE_SIMILARITY()
L1_DISTANCE()
L2_DISTANCE()

こっちは何となく分かる

COSINE_SIMILARITY

COSINE_SIMILARITY([0,1], [1,0]) // 0って書いてる…わからん…上で何となく分かると書いたのは何だったのか…
調べたら、コサイン類似度っていうのを求めるのがわかった(各ベクトルのなす角を求める)

\vec{a} \cdot \vec{b} = |\vec{a}||\vec{b}|cos\theta \\ cos\theta = \dfrac{\vec{a} \cdot \vec{b}}{|\vec{a}||\vec{b}|}

cos\thetaを求める

AqlValue Functions::CosineSimilarity(
    arangodb::aql::ExpressionContext* expressionContext,
    AstNode const& node,
    VPackFunctionParameters const& parameters) {

  auto cosineSimilarityFunc = [expressionContext, &node]
        (const VPackSlice lhs, const VPackSlice rhs, const VPackValueLength& length) {

    double numerator{};
    double lhsSum{};
    double rhsSum{};

    for (VPackValueLength i = 0; i < length; ++i) {
      auto lhsSlice = lhs.at(i);
      auto rhsSlice = rhs.at(i);
      if (!lhsSlice.isNumber() || !rhsSlice.isNumber()) {
        registerWarning(expressionContext,
                        getFunctionName(node).c_str(),
                        TRI_ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH);
        return AqlValue(AqlValueHintNull());
      }

      double lhsVal = lhsSlice.getNumber<double>();
      double rhsVal = rhsSlice.getNumber<double>();

      numerator += lhsVal * rhsVal;
      lhsSum += lhsVal * lhsVal;
      rhsSum += rhsVal * rhsVal;
    }

    double denominator = std::sqrt(lhsSum) * std::sqrt(rhsSum);
    if (denominator == 0.0) {
      registerWarning(expressionContext,
                      getFunctionName(node).c_str(),
                      TRI_ERROR_QUERY_INVALID_ARITHMETIC_VALUE);
      return AqlValue(AqlValueHintNull());
    }

    return ::numberValue(numerator / denominator, true);
  };

  return DistanceImpl(expressionContext, node, parameters, cosineSimilarityFunc);
}

numeratorで内積算出、lhsSumrhsSumで大きさ(累乗)なので多分間違いない

L1_DISTANCE

L1_DISTANCE([-1,-1], [2,2]) // 6ってなってるのでグラフにおいてXかY方向しか動けない(斜め不可)ときにおいての距離の算出

AqlValue Functions::L1Distance(
    arangodb::aql::ExpressionContext* expressionContext,
    AstNode const& node,
    VPackFunctionParameters const& parameters) {

  auto L1DistFunc = [expressionContext, &node]
        (const VPackSlice lhs, const VPackSlice rhs, const VPackValueLength& length) {

    double dist{};

    for (VPackValueLength i = 0; i < length; ++i) {
      auto lhsSlice = lhs.at(i);
      auto rhsSlice = rhs.at(i);
      if (!lhsSlice.isNumber() || !rhsSlice.isNumber()) {
        registerWarning(expressionContext,
                        getFunctionName(node).c_str(),
                        TRI_ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH);
        return AqlValue(AqlValueHintNull());
      }

      dist += std::abs(lhsSlice.getNumber<double>() -
                       rhsSlice.getNumber<double>());
    }

    return ::numberValue(dist, true);
  };

  return DistanceImpl(expressionContext, node, parameters, L1DistFunc);
}

dist += std::abs(lhsSlice.getNumber<double>() - rhsSlice.getNumber<double>());ってなってるので多分間違いない

L2_DISTANCE

L2_DISTANCE([1,1], [5,2]) // 4.1231056256176606ってなってるので2点間での距離の算出

AqlValue Functions::L2Distance(
    arangodb::aql::ExpressionContext* expressionContext,
    AstNode const& node,
    VPackFunctionParameters const& parameters) {

  auto L2DistFunc = [expressionContext, &node]
        (const VPackSlice lhs, const VPackSlice rhs, const VPackValueLength& length) {

    double dist{};

    for (VPackValueLength i = 0; i < length; ++i) {
      auto lhsSlice = lhs.at(i);
      auto rhsSlice = rhs.at(i);
      if (!lhsSlice.isNumber() || !rhsSlice.isNumber()) {
        registerWarning(expressionContext,
                        getFunctionName(node).c_str(),
                        TRI_ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH);
        return AqlValue(AqlValueHintNull());
      }

      double diff = lhsSlice.getNumber<double>() - rhsSlice.getNumber<double>();

      dist += std::pow(diff, 2);
    }

    return ::numberValue(std::sqrt(dist), true);
  };

  return DistanceImpl(expressionContext, node, parameters, L2DistFunc);
}

dist += std::pow(diff, 2);で2乗してreturn ::numberValue(std::sqrt(dist), true);で平方根求めてるので多分間違いない

Discussion