Проблема с извлечением атрибутов с плавающей точкой в ​​Sphinx с использованием Node.js - PullRequest
0 голосов
/ 13 марта 2012

Я пытался получить данные о сфинксе, используя Node.js и известняк.Я получил все от сфинкса вместо значения с плавающей точкой.В моем Сфинксе индекс Высота определяется как значение с плавающей запятой ("sql_attr_float = Height"), но Node.js возвращает некоторое целочисленное значение.

Например: если значение высоты в сфинксе равно 172,72, то я получил "1127004242"из Node.js

Пожалуйста, помогите мне в этом.

Ниже приведена функция, используемая в файле известняка, который читает данные сфинкса,

proto.toReader = function toReader() {
  var offset = 0, length = this.length, buffer = this;
  return {
    empty: function empty() {
      return offset >= length;
    },
    int64: function shiftInt64() {
      var hi_low_pair = buffer.int64Read(offset);
      offset += 8;
      return hi_low_pair;
    },
    int32: function shiftInt32() {
      var number = buffer.int32Read(offset);
      offset += 4;
      return number;
    },
    int16: function shiftInt16() {
      var number = buffer.int16Read(offset);
      offset += 2;
      return number;
    },
    buffer: function shiftBuffer(length) {
      var b = buffer.slice(offset, offset + length);
      offset += length;
      return b;
    },
    string: function shiftString(length) {
      var string = buffer.toString('utf8', offset, offset + length);
      offset += length;
      return string;
    },
    cstring: function shiftCstring() {
      var end = offset;
      while (buffer[end] > 0 && end < length) { end++; }
      var string = buffer.toString('utf8', offset, end);
      offset = end + 1;
      return string;
    },
    lstring: function shiftLString() {
      var length = buffer.int32Read(offset);
      offset += 4;          

      if(!isNaN(length) && !isNaN(offset)){
        length = length;
        var string = buffer.toString('utf8', offset, offset + length);
      }else{
        var string = "";
      }   

      offset += length;
      return string;
    },  
    multicstring: function shiftMulticstring() {
      var fields = [];
      while (buffer[offset] > 0) {
        fields.push(this.cstring());
      }
      offset++;
      return fields;
    },
    hash: function shiftHash() {
      var hash = {};
      while (buffer[offset] > 0) {
        hash[this.cstring()] = this.cstring();
      }
      offset++;
      return hash;
    }
  };
};

1 Ответ

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

Хмм, строка 715, из https://github.com/kurokikaze/limestone/blob/master/limestone.js имеет

            // FLOAT size attributes (32 bits)
            if (output.attributes[attribute].type == Sphinx.attribute.FLOAT) {
                attr_value = response.int32();
                match.attrs[output.attributes[attribute].name] = attr_value;
                continue;
            }

Так что это просто чтение float как int32!

И, как вы говорите toReader / makeWriter отсутствует floatметоды.

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

Проверяя код SphinxAPI, вот как это делается в php:

                                    // handle floats
                                    if ( $type==SPH_ATTR_FLOAT )
                                    {
                                            list(,$uval) = unpack ( "N*", substr ( $response, $p, 4 ) ); $p += 4;
                                            list(,$fval) = unpack ( "f*", pack ( "L", $uval ) );
                                            $attrvals[$attr] = $fval;
                                            continue;
                                    }

Java может сделать это несколько наивно

                                            /* handle floats */
                                            if ( type==SPH_ATTR_FLOAT )
                                            {
                                                    docInfo.attrValues.add ( attrNumber, new Float ( in.readFloat() ) );
                                                    continue;
                                            }

Для портов упаковки / распаковки: упаковать / распаковать функции для node.js

...