Java: Hadoop: MapReduce: использование фильтров для извлечения данных из hbase, сравнение int / string - PullRequest
0 голосов
/ 19 марта 2012

Я хочу получить данные из hbase для моей работы с mapreduce, но я хочу отфильтровать их раньше. Я только хочу получить данные, которые содержат столбец с идентификатором, который больше или равен minId.

Я храню Id в HBase в виде строки. Теперь мне интересно, если этот фильтр работает тогда.

int minId = 123; Filter filter = new ValueFilter(CompareFilter.CompareOp.GREATER_OR_EQUAL, new BinaryComparator(Bytes.toBytes(minId)));

Как HBase может фильтровать мои данные, если сохраненный идентификатор является строкой, а значение, используемое для сравнения данных, является целым числом? Может ли это работать? Если я использую строку для моего BinaryComparator (так что String mindId = "123"; будет ли это работать тогда?

Спасибо за ответы!

1 Ответ

1 голос
/ 20 марта 2012

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

То есть «123»> «121», но «123» <«21». Если вы обнуляете его, он становится «123» и «021», и тогда вы получите правильный результат. </p>

Другой идеей может быть создание компаратора, соответствующего вашим требованиям. Просто переопределите метод BinaryComparator compareTo (). Может быть что-то вроде этого (я просто редактирую метод CompareTo в PureJavaComparator ):

  @Override
  public int compareTo(byte[] buffer1, int offset1, int length1,
      byte[] buffer2, int offset2, int length2) {
    // Remove leading zeros
    int l1 = getNumLeadingZeros(buffer1, offset1, length1);
    int l2 = getNumLeadingZeros(buffer2, offset2, length2);
    offset1=offset1+l1;
    length1=length1-l1;
    offset2=offset2+l2;
    length2=length2-l2;

    // If lengths are different, just return the longer int
    int ldiff = length1-length2;
    if(ldiff != 0) return ldiff;

    // If lengths are same, we can use the usual lexical comparator
    return Bytes.compareTo(buffer1, offset1, length1, buffer2, offset2, length2);
  }

  public int getNumLeadingZeros(byte[] arr, int offset, int length) {
      int ret = 0;
      byte zero = '0';
      int i=0;
      while(i<length && arr[offset+i]==zero) {
          ++ret;
      }
      return ret;
  }

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

...