#3 методы find и filter в lodash

Зачем нужны шаблоны?

Ранее мы уже видели код , который сам создаёт свой элемент:

Понятен ли этот код? Очевидно ли, какой HTML генерируют методы , ?

С первого взгляда – вряд ли. Нужно как минимум внимательно посмотреть и продумать код, чтобы разобраться, какая именно DOM-структура создаётся.

…А что, если нужно изменить создаваемый HTML? …А что, если эта задача досталась не программисту, который написал этот код, а верстальщику, который с HTML/CSS проекта знаком отлично, но этот JS-код видит впервые? Вероятность ошибок при этом зашкаливает за все разумные пределы.

К счастью, генерацию HTML можно упростить. Для этого воспользуемся библиотекой шаблонизации.

Пошаговое руководство по структуре

Пример может прояснить принципы хранения данных и их возможной интерпретации. Например, самый крупный заказ, которому соответствует самая длинная наблюдаемая цепочка в базовых данных AdventureWorksDW2012 , можно найти, используя следующий запрос:

По этим результатам видно, что заказы с номерами SO72656, SO58845 и SO70714 содержат самые крупные последовательности, по восемь элементов в каждой. Используя идентификаторы заказов, можно просмотреть данные конкретного заказа, чтобы увидеть, какие товары были приобретены и в каком порядке.

OrderNumber LineNumber Модель
SO58845 1 Mountain-500
SO58845 2 Шина LL Mountain
SO58845 3 Камера шины для велосипеда Mountain
SO58845 4 Набор крыльев для велосипеда Mountain
SO58845 5 Держатель фляги для велосипеда Mountain
SO58845 6 Фляга для воды
SO58845 7 Sport-100
SO58845 8 Кофта с длинными рукавами и эмблемой

Однако некоторые клиенты, купившие велосипед Mountain-500, могли приобрести разные товары. Чтобы просмотреть все товары, следующие за велосипедом Mountain-500, можно просмотреть список последовательностей в модели. Далее приведены пошаговые инструкции по просмотру этих последовательностей с помощью двух средств просмотра, доступных в службах Analysis Services.

Переименование записи + 6. Удаление записи

С придуманными ранее функциями-помощниками оставшаяся функциональность крайне проста:

let changeTitleTo => title => patch({  title: title});let hasTitle = title => matches({  title: title});let renameItem = (newTitle, oldTitle) => patch({  items: forAll(changeTitleTo(newTitle).onlyIf(hasTitle(oldTitle)).otherwise(_.identity))});let removeItem = (title) => patch({  items: removeIf(hasTitle(oldTitle))});

Все вместе

Давайте соберем все куски кода вместе. Я разделил определения функций на две группы. Первая группа состоит из более абстрактных и более переиспользуемых функций (высшего порядка). Вторая группа включает в себя функции, более зависимые от предметной области.

let _ = require('lodash/fp');function customizer(val, op){  if(_.isFunction(op)){    return op.apply(this, );  }  if(_.isRegExp(op)){    return op.test(val);  }}// general-purpose, higher-order functions:let patch = recipe => _.mergeWith(customizer, _, recipe);let matches = _.isMatchWith(customizer);let forAll = _.map;let removeIf = _.reject;let toggle = _.negate(_.identity);Function.prototype.onlyIf = function(condFn) {  return _.cond(]);};Function.prototype.otherwise = function(defaultFn) {  let noResult = _.flow();  return _.cond(, ]);};// domain-specific functions:let addItem = item => patch({  items: _.concat({title: item})});let complete = patch({  completed: true});let completeAll = patch({  items: forAll(complete)});let isCompleted = matches({  completed: true});let clearCompleted = patch({  items: removeIf(isCompleted)});let toggleItem = patch({  completed: toggle});let completeItemIf = condFn => patch({  items: forAll(complete.onlyIf(condFn).otherwise(_.identity))});let changeTitleTo = title => patch({  title: title});let hasTitle = title => matches({  title: title});let renameItem = (newTitle, oldTitle) => patch({  items: forAll(changeTitleTo(newTitle).onlyIf(hasTitle(oldTitle)).otherwise(_.identity))});let removeItem = (title) => patch({  items: removeIf(hasTitle(oldTitle))});// demo:let program = _.flow([  addItem('Learn Lodash'),  addItem('Learn FP'),  addItem('Write Blog Post'),  renameItem('Learn Functional Programming', 'Learn FP'),  completeItemIf(hasTitle(/Learn/))]);console.log(program({items: []}));// →// { //   items: [ //     { title: 'Write Blog Post' },//     { title: 'Learn Functional Programming', completed: true },//     { title: 'Learn Lodash', completed: true } //   ] // }

Вы также можете найти полный код и поиграться с ним в этом JS Fiddle.

Заключение

В этой статье мы исследовали возможности кастомизации библиотеки Lodash. В результате мы сделали простой, но мощный предметно-ориентированный язык для декларативного преобразования JSON-объектов в виде патчей(patches). Благодаря гибкости и расширяемости Lodash, мы сделали это, написав довольно небольшое количество строк кода.

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

Является ли этот функциональный подход лучше/чище/моднее/подставьте_свое_прилагательное, чем классический императивный подход? Я оставлю читателю этот вопрос на его усмотрение

Однако, независимо от ответа, определенно важно быть в курсе всех этих крутых функций кастомизации, предоставляемых Lodash

В следующей статье мы расширим наш пример интерфейсом пользователя и построим полностью работоспособное приложение списка To-Do. Оставайтесь на связи!

Функция _.template

Для работы с шаблоном в библиотеке LoDash есть функция .

Её аргументы:

Шаблон.
Необязательные настройки, например можно поменять разделители.

Эта функция запускает «компиляцию» шаблона и возвращает результат в виде функции, которую далее можно запустить с данными и получить строку-результат.

Вот так:

Пример выше похож на операцию «поиск-и-замена»: шаблон просто заменил на значение свойства .

Но возможность вставки JS-кода делает шаблоны сильно мощнее.

Например, вот шаблон для генерации списка от до :

Здесь в результат попал сначала текст , потом выполнился код , который последовательно сгенерировал элементы списка, и затем список был закрыт .

Installation

In a browser:

script src='https://cdn.jsdelivr.net/g/lodash@4(lodash.min.js+lodash.fp.min.js)'>script>
script>
// Loading `lodash.fp.js` converts `_` to its fp variant.
_.defaults({ 'a' 2, 'b' 2 })({ 'a' 1 });
// ➜ { 'a': 1, 'b': 2 }

// Use `noConflict` to restore the pre-fp variant.
var fp = _.noConflict();

_.defaults({ 'a' 1 }, { 'a' 2, 'b' 2 });
// ➜ { 'a': 1, 'b': 2 }
fp.defaults({ 'a' 2, 'b' 2 })({ 'a' 1 });
// ➜ { 'a': 1, 'b': 2 }
script>

In Node.js:

// Load the fp build.
var fp = require('lodash/fp');

// Load a method category.
var object = require('lodash/fp/object');

// Load a single method for smaller builds with browserify/rollup/webpack.
var extend = require('lodash/fp/extend');

Добавление узлов Slave

Для добавления новых узлов в кластер опять воспользуемся утилитой . Для присоединения сервера slave к master будем использовать команду:

./redis-trib.rb add-node --slave --master-id  ip.of.server1:6381 ip.of.server3:6381

В результате должен вернуться ответ:

>>> Adding node ip.of.server1:6381 to cluster ip.of.server3:6381
>>> Performing Cluster Check (using node ip.of.server3:6381)
M:  ip.of.server3:6381
   slots:10923-16383 (5461 slots) master
   0 additional replica(s)
M:  ip.of.server1:6379
   slots:0-5460 (5461 slots) master
   0 additional replica(s)
M:  ip.of.server2:6380
   slots:5461-10922 (5462 slots) master
   0 additional replica(s)
 All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
 All 16384 slots covered.
>>> Send CLUSTER MEET to node ip.of.server1:6381 to make it join the cluster.
Waiting for the cluster to join...
>>> Configure node as replica of ip.of.server3:6381.

Повторите это действие для двух оставшихся узлов:

./redis-trib.rb add-node --slave --master-id  ip.of.server2:6379 ip.of.server1:6379

./redis-trib.rb add-node --slave --master-id  ip.of.server3:6380 ip.of.server2:6380

Содержимое модели для модели кластеризации

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

Сведения о столбцах общего назначения MODEL_CATALOG, MODEL_NAME и других в наборе строк схемы см. в разделе Содержимое модели интеллектуального анализа данных (службы Analysis Services — интеллектуальный анализ данных).

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

MODEL_NAME
Имя модели.

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

NODE_NAME
Всегда совпадает с NODE_UNIQUE_NAME.

NODE_UNIQUE_NAME
Уникальный идентификатор узла в модели. Это значение невозможно изменить.

NODE_TYPE
Выходными данными модели кластеризации являются узлы следующих типов.

Идентификатор и имя узла Description
1 (модель) Корневой узел для модели.
5 (кластер) Содержит количество вариантов в кластере, характеристики вариантов в кластере и статистические данные, которые описывают значения в кластере.

NODE_CAPTION
Понятное имя, применяемое для отображения. При создании модели в качестве заголовка автоматически используется значение NODE_UNIQUE_NAME. Но предусмотрена возможность изменить значение NODE_CAPTION для обновления отображаемого имени кластера либо программным путем, либо с использованием средства просмотра.

Примечание

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

CHILDREN_CARDINALITY
Оценка количества дочерних узлов, которые имеет данный узел.

Родительский узел Указывает количество кластеров в модели.

Узлы кластера Всегда 0.

PARENT_UNIQUE_NAME
Уникальное имя родителя узла.

Родительский узел Всегда имеет значение NULL

Узлы кластера Обычно имеют значение 000.

NODE_DESCRIPTION
Описание узла.

Родительский узел Всегда имеет значение (All) .

Узлы кластера Список с разделителями-запятыми основных атрибутов, которыми данный кластер отличается от других кластеров.

NODE_RULE
Не используется для моделей кластеризации.

MARGINAL_RULE
Не используется для моделей кластеризации.

NODE_PROBABILITY
Вероятность, связанная с этим узлом. Родительский узел Всегда 1.

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

MARGINAL_PROBABILITY
Вероятность доступа к узлу от родительского узла. В модели кластеризации граничная вероятность всегда совпадает с вероятностью узла.

NODE_DISTRIBUTION
Таблица, содержащая гистограмму вероятности узла.

Родительский узел См. введение к этому разделу.

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

NODE_SUPPORT
Число вариантов, поддерживаемое этим узлом. Родительский узел Указывает количество обучающих вариантов для всей модели.

Узлы кластера Указывает размер кластера как количество вариантов.

Примечание . Если в модели используется кластеризация K-средних, то каждый вариант может принадлежать только к одному кластеру. Но если в модели используется кластеризация по методу EM, то каждый вариант может принадлежать к различным кластерам и варианту присваивается значение взвешенного расстояния для каждого кластера, к которому он принадлежит. Поэтому для моделей EM сумма несущих множеств отдельных кластеров больше несущего множества всей модели.

MSOLAP_MODEL_COLUMN
Не используется для моделей кластеризации.

MSOLAP_NODE_SCORE
Отображает оценку, связанную с узлом.

Родительский узел . Оценка байесовского информационного критерия (BIC) для модели кластеризации.

Узлы кластера Всегда 0.

MSOLAP_NODE_SHORT_CAPTION
Метка, используемая для отображения. Этот заголовок нельзя изменить.

Родительский узел Тип модели: кластерная модель

Узлы кластера Имя кластера. Пример. Кластер 1.

Пометка записи как завершенной

Определение функции, переключающей флаг выполнения записи, простое:

let toggle = _.negate(_.identity);let toggleItem = patch({  completed: toggle});

Переключить записи в списке To-Do и оставить другие записи нетронутыми — это совершенно другая история. Чтобы реализовать это, мы сначала создадим новую функцию высшего порядка, которая будет вызывать функцию, переданную в качестве параметра в зависимости от переданного предиката:

function onlyIf(fn, condFn){  return function(){    let args = _.toArray(arguments);    if(condFn.apply(this, args)){      return fn.apply(this, args);    }  };}function pow(n) { return n*n; }let powN = onlyIf(pow, _.isNumber);powN(4);// → 16powN('4');// → undefined

Функция выглядит излишне императивной. Возможно Lodash может как-нибудь помочь нам с этим? Конечно может! Взгляните на . Теперь мы имеем:

let onlyIf = (fn, condFn) => _.cond(]);let powN = onlyIf(pow, _.isNumber);powN(4);// → 16

Но нам нужна ещё одна функция:

let otherwise = (fn, defaultFn) => _.cond(), fn]      ]);let powN = otherwise(onlyIf(pow, _.isNumber), _.constant('number expected!'));powN(4);// → 16powN('4');// → number expected!

Должен сказать, что выглядит довольно экстремально. Возможно, императивная версия будет значительно более понятной. Я оставлю задачу (изменить эту функцию) читателю в качестве упражнения. Фрагмент отнюдь не лучше. Он не выглядит естественно. Определенно он менее читаем, чем . Возможно мы зашли слишком далеко. Но давайте попробуем еще один трюк, перед тем как сдаваться. Давайте присвоим обе функции в и передадим исходную функцию, как параметр :

Function.prototype.onlyIf = function(condFn) {  return _.cond(]);};Function.prototype.otherwise = function(defaultFn) {  let noResult = _.flow();  return _.cond(, ]);};let powN = pow.onlyIf(_.isNumber).otherwise(_.constant('number expected!'));powN(4);// → 16powN('4');// → number expected!

Нам пришлось поменять стрелочную нотацию () на выражение с , так как стрелочные функции не создают собственный параметр . Теперь мы можем вернуться к нашему исходному заданию: переключение одной конкретной записи.

let completeItemIf = (condFn) => patch({  items: forAll(complete.onlyIf(condFn).otherwise(_.identity))});var completeLearning = completeItemIf(_.matches({title: 'Learn FP'}));completeLearning({  items: });// →// {//   items: [//     { title: 'Learn FP', completed: true },//     { title: 'Read tutorial & learn Lodash' }//   ]// }

Установка Redis на каждый сервер

В зависимости от используемой версии Linux, может быть доступна установка Redis через менеджер пакетов. В данном руководстве мы рассмотрим установку текущей стабильной версии из исходного кода.

Сначала установите зависимости необходимые для сборки зависимости:

sudo apt-get update && sudo apt-get upgrade
sudo apt install make gcc libc6-dev tcl

Скачайте текущую стабильную ветку и извлеките исходный код из архива:

wget http://download.redis.io/redis-stable.tar.gz
tar xvzf redis-stable.tar.gz
cd redis-stable
sudo make install

Убедитесь, что тесты сборки проходят успешно:

make test

При успешном завершении, в консоли будет ответ:

\o/ All tests passed without errors!

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

Использование сведений о последовательностяхUsing Sequence Information

Распространенным сценарием для алгоритма кластеризации последовательностей является отслеживание щелчков мыши пользователя на веб-сайте.A common scenario for sequence clustering is to track user clicks on a Web site. Например, если данные получены из записей о покупках, совершенных на веб-сайте электронной коммерции Adventure Works, с помощью результирующей модели кластеризации последовательностей можно выявить закономерности в поведении пользователей, изменить структуру узла электронной коммерции, чтобы устранить проблемы навигации или увеличить продажи.For example, if the data were from records of customer purchases on the Adventure Works e-commerce Web site, the resulting sequence clustering model could be used to infer user behavior, to redesign the e-commerce site to solve navigation problems, or to promote sales.

Например, анализ может показать, что пользователи, независимо от демографических параметров, всегда следуют вдоль определенной цепочки товаров.For example, analysis might show that users always follow a particular chain of products, regardless of demographics. Кроме того, может обнаружиться, что пользователи часто выходят с сайта, после того как щелкнут определенный товар.Also, you might find that users frequently exit the site after clicking on a particular product. С учетом этого факта можно задаться вопросом — какие дополнительные пути навигации можно предложить пользователям, чтобы побудить их остаться на веб-сайте?Given that finding, you might ask what additional paths you could provide to users that would induce users to stay on the Web site.

Если нет дополнительных данных, по которым можно классифицировать пользователей, то можно просто использовать сведения о последовательностях для сбора данных о навигации, чтобы лучше представлять себе общую картину использования веб-узла.If you do not have additional information to use in classifying your users, then you can simply use the sequence information to collect data about navigation to better understand overall behavior. Однако если можно собрать сведения о клиентах и сопоставить их с базой данных клиентов, можно объединить возможности кластеризации с прогнозами, основанными на последовательностях, чтобы выработать рекомендации, привязанные к отдельным пользователям. Также возможно построить рекомендации на основе пути навигации, ведущего к текущей странице.However, if you can collect information about customers and match that information with your customer database, you can combine the power of clustering with prediction on sequences to provide recommendations that are tailored to the user, or perhaps based on the path of navigation to the current page.

Другим использованием обширных данных по состояниям и переходам, обрабатываемых моделью кластеризации, является определение возможных путей, которые никогда не используются.Another use of the extensive state and transition information compiled by a sequence clustering model is to determine which possible paths are never used. Например, если на страницах 1—4 зарегистрировано множество посетителей, но никто из них никогда не переходил на страницу 5, разумно проверить наличие возможных проблем, препятствующих переходу на страницу 5.For example, if you have many visitors going to pages 1-4, but visitors never continue on to page 5, you might investigate whether there are problems that prevent navigation to page 5. Это можно сделать, запросив содержимое модели и сравнив результат со списком возможных путей.You can do this by querying the model content, and comparing it against a list of possible paths. Графики, которые показывают все пути навигации по сайту, можно создать программным образом или с помощью разнообразных средств анализа веб-сайтов.Graphs that tell you all the navigation paths in a Web site can be created programmatically, or by using a variety of site analysis tools.

Сведения о том, как получить список наблюдаемых путей с помощью запроса содержимого модели, а также другие примеры запросов, основанных на модели кластеризации последовательностей, см. в разделе Примеры запросов к модели кластеризации последовательностей.To find out how to obtain the list of observed paths by querying the model content, and to see other examples of queries on a sequence clustering model, see Sequence Clustering Model Query Examples.

Convert

Although & its method modules come pre-converted, there are times
when you may want to customize the conversion. That’s when the method
comes in handy.

// Every option is `true` by default.
var _fp = fp.convert({
  // Specify capping iteratee arguments.
  'cap' true,
  // Specify currying.
  'curry' true,
  // Specify fixed arity.
  'fixed' true,
  // Specify immutable operations.
  'immutable' true,
  // Specify rearranging arguments.
  'rearg' true
});

// The `convert` method is available on each method too.
var mapValuesWithKey = fp.mapValues.convert({ 'cap' false });

// Here’s an example of disabling iteratee argument caps to access the `key` param.
mapValuesWithKey(function(value, key) {
  return key == 'a' ? -1  value;
})({ 'a' 1, 'b' 1 });
// => { 'a': -1, 'b': 1 }

Manual conversions are also possible with the module.

var convert = require('lodash/fp/convert');

// Convert by name.
var assign = convert('assign', require('lodash.assign'));

// Convert by object.
var fp = convert({
  'assign' require('lodash.assign'),
  'chunk' require('lodash.chunk')
});

// Convert by `lodash` instance.
var fp = convert(lodash.runInContext());

Список функций

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

прогнозирующую функцию Использование
Cluster (расширения интеллектуального анализа данных) Возвращает кластер, в котором с наибольшей вероятностью содержится входной вариант.
ClusterDistance (расширения интеллектуального анализа данных) Возвращает расстояние до входного варианта от указанного кластера, а если кластер не указан, то расстояние до входного варианта от наиболее вероятного кластера. Эту функцию можно использовать с любой моделью кластеризации (максимизация ожиданий, K-среднее и т. д.), но полученные результаты будут зависеть от алгоритма.
ClusterProbability (расширения интеллектуального анализа данных) Возвращает вероятность того, что входной вариант принадлежит определенному кластеру.
IsInNode (расширения интеллектуального анализа данных) Указывает, содержит ли заданный узел текущий вариант.
PredictAdjustedProbability (расширения интеллектуального анализа данных) Возвращает настроенную вероятность указанного состояния.
PredictAssociation (расширения интеллектуального анализа данных) Прогнозирует ассоциированное членство.
PredictCaseLikelihood (расширения интеллектуального анализа данных) Возвращает достоверность, с которой входной вариант соответствует существующей модели.
PredictHistogram (расширения интеллектуального анализа данных) Возвращает таблицу, представляющую гистограмму прогноза данного столбца.
PredictNodeId (расширения интеллектуального анализа данных) Возвращает значение параметра Node_ID узла, к которому относится вариант.
PredictProbability (расширения интеллектуального анализа данных) Возвращает вероятность для указанного состояния.
PredictSequence (расширения интеллектуального анализа данных) Дает предварительную оценку будущих значений заданной последовательности данных.
PredictStdev (расширения интеллектуального анализа данных) Возвращает прогнозируемое среднеквадратичное отклонение для заданного столбца.
PredictSupport (расширения интеллектуального анализа данных) Возвращает опорное значение для указанного состояния.
PredictVariance (расширения интеллектуального анализа данных) Возвращает дисперсию указанного столбца.

Список функций, общих для всех алгоритмов Microsoft, см. в статье Общие функции прогнозирования (расширения интеллектуального анализа данных). Синтаксис отдельных функций см. в статье Справочник по функциям расширений интеллектуального анализа данных (расширения интеллектуального анализа данных).

4a. Собственные функции соответствия

Как вы можете видеть в коде выше, чтобы завершить одну запись, нам нужно передать её полное название. Это немного неудобно. Что если мы хотим завершить каждую запись, содержащую «Learn» или «learn» в названии? Нам нужна собственная функция соответствия, которая также принимает регулярные выражения. Чтобы достигнуть этого, мы будем использовать уже знакомую функцию кастомизаторов Lodash, но в этот раз мы применим её с функцией вместо .

Мы можем переиспользовать наш и расширить его поддержкой регулярных выражений:

function customizer(val, operator){  if(_.isFunction(operator)){    return operator.apply(this, );  }  if(_.isRegExp(operator)){    return operator.test(val);  }}let matches = _.isMatchWith(customizer);

Улучшенный эффективно преобразовывает в нечно даже более гибкое чем , поскольку позволяет проверять соответствие свойств объекта как с фиксированными значениями, так и c регулярными выражениями и c предикатами:

let involvesLearning = matches({ title: /earn/ });involvesLearning({  title: 'Learn Function Programming'});// → trueinvolvesLearning({  title: 'Walk the dog'});// → falselet hasNonEmptyTitle = matches({ title: _.negate(_.isEmpty) });hasNonEmptyTitle({  title: ''})// → false

RemarksRemarks

(../../includes/ssasnoversion-md.md)] предоставляется несколько методов создания модели кластеризации.(../../includes/ssasnoversion-md.md)] provides multiple methods for creating a clustering model.Если неизвестно, какие методы использовались для создания модели, с которой происходит работа, метаданные модели можно получить программным путем, с помощью клиента ADOMD или объектов AMO, либо с помощью запроса к набору строк схемы интеллектуального анализа данных.If you do not know which method was used to create the model that you are working with, you can retrieve the model metadata programmatically, by using an ADOMD client or AMO, or by querying the data mining schema rowset.Дополнительные сведения см. в разделе (query-the-parameters-used-to-create-a-mining-model.md).For more information, see (query-the-parameters-used-to-create-a-mining-model.md).Структура и содержимое модели остаются теми же, независимо от используемой модели кластеризации или параметров.The structure and content of the model stay the same, regardless of which clustering method or parameters you use.См. также:See Also(mining-model-content-analysis-services-data-mining.md) (mining-model-content-analysis-services-data-mining.md) (data-mining-model-viewers.md) (data-mining-model-viewers.md) (microsoft-clustering-algorithm.md) (microsoft-clustering-algorithm.md) Запросы интеллектуального анализа данныхData Mining Queries

Распределение данных

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

redis-cli -c -h ip.of.server1 -p 6379

Используйте команду для просмотра информации о состоянии кластера, например, его размер, хэш слоты, ошибки, если они есть.

ip.of.server1:6379>CLUSTER INFO
cluster_state:ok
cluster_slots_assigned:16384
cluster_slots_ok:16384
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:6
cluster_size:3
cluster_current_epoch:6
cluster_my_epoch:1
cluster_stats_messages_ping_sent:8375
cluster_stats_messages_pong_sent:9028
cluster_stats_messages_meet_sent:1
cluster_stats_messages_sent:17404
cluster_stats_messages_ping_received:9022
cluster_stats_messages_pong_received:8376
cluster_stats_messages_meet_received:6
cluster_stats_messages_received:17404

Для проверки репликации master/slave используйте , которая возвращает информацию об узлах slave.

ip.of.server1:6379>INFO replication
role:master
connected_slaves:1
slave0:ip=ip.of.server1,port=6381,state=online,offset=213355,lag=1
master_replid:cd2e27cba094f2e7ed38b0313dcd6a979ab29b7a
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:213355
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:197313
repl_backlog_histlen:16043

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

ip.of.server1:6379> SET John Adams
-> Redirected to slot  located at ip.of.server2:6380
OK
ip.of.server2:6380> SET James Madison
-> Redirected to slot  located at ip.of.server1:6379
OK
ip.of.server1:6379> SET Andrew Jackson
-> Redirected to slot  located at ip.of.server3:6381
OK
ip.of.server3:6381> GET John
-> Redirected to slot  located at ip.of.server2:6380
"Adams"
ip.of.server2:6380>
Ссылка на основную публикацию