示例#1
0
 public function update(XSDocument $doc, $add = false)
 {
     if ($doc->beforeSubmit($this) === false) {
         return $this;
     }
     $fid = $this->xs->getFieldId();
     $key = $doc->f($fid);
     if ($key === null || $key === '') {
         throw new XSException('Missing value of primary key (FIELD:' . $fid . ')');
     }
     $cmd = new XSCommand(XS_CMD_INDEX_REQUEST, XS_CMD_INDEX_REQUEST_ADD);
     if ($add !== true) {
         $cmd->arg1 = XS_CMD_INDEX_REQUEST_UPDATE;
         $cmd->arg2 = $fid->vno;
         $cmd->buf = $key;
     }
     $cmds = array($cmd);
     foreach ($this->xs->getAllFields() as $field) {
         if (($value = $doc->f($field)) !== null) {
             $varg = $field->isNumeric() ? XS_CMD_VALUE_FLAG_NUMERIC : 0;
             $value = $field->val($value);
             if (!$field->hasCustomTokenizer()) {
                 $wdf = $field->weight | ($field->withPos() ? XS_CMD_INDEX_FLAG_WITHPOS : 0);
                 if ($field->hasIndexMixed()) {
                     $cmds[] = new XSCommand(XS_CMD_DOC_INDEX, $wdf, XSFieldScheme::MIXED_VNO, $value);
                 }
                 if ($field->hasIndexSelf()) {
                     $wdf |= $field->isNumeric() ? 0 : XS_CMD_INDEX_FLAG_SAVEVALUE;
                     $cmds[] = new XSCommand(XS_CMD_DOC_INDEX, $wdf, $field->vno, $value);
                 }
                 if (!$field->hasIndexSelf() || $field->isNumeric()) {
                     $cmds[] = new XSCommand(XS_CMD_DOC_VALUE, $varg, $field->vno, $value);
                 }
             } else {
                 if ($field->hasIndex()) {
                     $terms = $field->getCustomTokenizer()->getTokens($value, $doc);
                     if ($field->hasIndexSelf()) {
                         $wdf = $field->isBoolIndex() ? 1 : $field->weight | XS_CMD_INDEX_FLAG_CHECKSTEM;
                         foreach ($terms as $term) {
                             if (strlen($term) > 200) {
                                 continue;
                             }
                             $term = strtolower($term);
                             $cmds[] = new XSCommand(XS_CMD_DOC_TERM, $wdf, $field->vno, $term);
                         }
                     }
                     if ($field->hasIndexMixed()) {
                         $mtext = implode(' ', $terms);
                         $cmds[] = new XSCommand(XS_CMD_DOC_INDEX, $field->weight, XSFieldScheme::MIXED_VNO, $mtext);
                     }
                 }
                 $cmds[] = new XSCommand(XS_CMD_DOC_VALUE, $varg, $field->vno, $value);
             }
         }
         if (($terms = $doc->getAddTerms($field)) !== null) {
             $wdf1 = $field->isBoolIndex() ? 0 : XS_CMD_INDEX_FLAG_CHECKSTEM;
             foreach ($terms as $term => $wdf) {
                 $term = strtolower($term);
                 if (strlen($term) > 200) {
                     continue;
                 }
                 $wdf2 = $field->isBoolIndex() ? 1 : $wdf * $field->weight;
                 while ($wdf2 > XSFieldMeta::MAX_WDF) {
                     $cmds[] = new XSCommand(XS_CMD_DOC_TERM, $wdf1 | XSFieldMeta::MAX_WDF, $field->vno, $term);
                     $wdf2 -= XSFieldMeta::MAX_WDF;
                 }
                 $cmds[] = new XSCommand(XS_CMD_DOC_TERM, $wdf1 | $wdf2, $field->vno, $term);
             }
         }
         if (($text = $doc->getAddIndex($field)) !== null) {
             if (!$field->hasCustomTokenizer()) {
                 $wdf = $field->weight | ($field->withPos() ? XS_CMD_INDEX_FLAG_WITHPOS : 0);
                 $cmds[] = new XSCommand(XS_CMD_DOC_INDEX, $wdf, $field->vno, $text);
             } else {
                 $wdf = $field->isBoolIndex() ? 1 : $field->weight | XS_CMD_INDEX_FLAG_CHECKSTEM;
                 $terms = $field->getCustomTokenizer()->getTokens($text, $doc);
                 foreach ($terms as $term) {
                     if (strlen($term) > 200) {
                         continue;
                     }
                     $term = strtolower($term);
                     $cmds[] = new XSCommand(XS_CMD_DOC_TERM, $wdf, $field->vno, $term);
                 }
             }
         }
     }
     $cmds[] = new XSCommand(XS_CMD_INDEX_SUBMIT);
     if ($this->_bufSize > 0) {
         $this->appendBuffer(implode('', $cmds));
     } else {
         for ($i = 0; $i < count($cmds) - 1; $i++) {
             $this->execCommand($cmds[$i]);
         }
         $this->execCommand($cmds[$i], XS_CMD_OK_RQST_FINISHED);
     }
     $doc->afterSubmit($this);
     return $this;
 }
示例#2
0
 /**
  * 更新索引文档
  * 该方法相当于先根据主键删除已存在的旧文档, 然后添加该文档
  * 如果你能明确认定是新文档, 则建议使用 {@link add}
  * @param XSDocument $doc
  * @param bool $add 是否为新增文档, 已有数据中不存在同一主键的其它数据
  * @return XSIndex 返回自身对象以支持串接操作
  */
 public function update(XSDocument $doc, $add = false)
 {
     // before submit
     if ($doc->beforeSubmit($this) === false) {
         return $this;
     }
     // check primary key of document
     $fid = $this->xs->getFieldId();
     $key = $doc->f($fid);
     if ($key === null || $key === '') {
         throw new XSException('Missing value of primarky key (FIELD:' . $fid . ')');
     }
     // request cmd
     $cmd = new XSCommand(CMD_INDEX_REQUEST, CMD_INDEX_REQUEST_ADD);
     if ($add !== true) {
         $cmd->arg1 = CMD_INDEX_REQUEST_UPDATE;
         $cmd->arg2 = $fid->vno;
         $cmd->buf = $key;
     }
     $cmds = array($cmd);
     // document cmds
     foreach ($this->xs->getAllFields() as $field) {
         // value
         if (($value = $doc->f($field)) !== null) {
             $varg = $field->isNumeric() ? CMD_VALUE_FLAG_NUMERIC : 0;
             $value = $field->val($value);
             if (!$field->hasCustomTokenizer()) {
                 // internal tokenizer
                 $wdf = $field->weight | ($field->withPos() ? CMD_INDEX_FLAG_WITHPOS : 0);
                 if ($field->hasIndexMixed()) {
                     $cmds[] = new XSCommand(CMD_DOC_INDEX, $wdf, XSFieldScheme::MIXED_VNO, $value);
                 }
                 if ($field->hasIndexSelf()) {
                     $wdf |= $field->isNumeric() ? 0 : CMD_INDEX_FLAG_SAVEVALUE;
                     $cmds[] = new XSCommand(CMD_DOC_INDEX, $wdf, $field->vno, $value);
                 }
                 // add value
                 if (!$field->hasIndexSelf() || $field->isNumeric()) {
                     $cmds[] = new XSCommand(CMD_DOC_VALUE, $varg, $field->vno, $value);
                 }
             } else {
                 // add index
                 if ($field->hasIndex()) {
                     $terms = $field->getCustomTokenizer()->getTokens($value, $doc);
                     // self: [bool term, NOT weight, NOT stem, NOT pos]
                     if ($field->hasIndexSelf()) {
                         foreach ($terms as $term) {
                             $term = strtolower($term);
                             $cmds[] = new XSCommand(CMD_DOC_TERM, 1, $field->vno, $term);
                         }
                     }
                     // mixed: [use default tokenizer]
                     if ($field->hasIndexMixed()) {
                         $mtext = implode(' ', $terms);
                         $cmds[] = new XSCommand(CMD_DOC_INDEX, $field->weight, XSFieldScheme::MIXED_VNO, $mtext);
                     }
                 }
                 // add value
                 $cmds[] = new XSCommand(CMD_DOC_VALUE, $varg, $field->vno, $value);
             }
         }
         // process add terms
         if (($terms = $doc->getAddTerms($field)) !== null) {
             // ignore weight for bool index
             $wdf1 = $field->isBoolIndex() ? 0 : CMD_INDEX_FLAG_CHECKSTEM;
             foreach ($terms as $term => $wdf) {
                 $term = strtolower($term);
                 $wdf2 = $field->isBoolIndex() ? 1 : $wdf * $field->weight;
                 while ($wdf2 > XSFieldMeta::MAX_WDF) {
                     $cmds[] = new XSCommand(CMD_DOC_TERM, $wdf1 | XSFieldMeta::MAX_WDF, $field->vno, $term);
                     $wdf2 -= XSFieldMeta::MAX_WDF;
                 }
                 $cmds[] = new XSCommand(CMD_DOC_TERM, $wdf1 | $wdf2, $field->vno, $term);
             }
         }
         // process add text
         if (($text = $doc->getAddIndex($field)) !== null) {
             if (!$field->hasCustomTokenizer()) {
                 $wdf = $field->weight | ($field->withPos() ? CMD_INDEX_FLAG_WITHPOS : 0);
                 $cmds[] = new XSCommand(CMD_DOC_INDEX, $wdf, $field->vno, $text);
             } else {
                 // NOT pos
                 $wdf = $field->isBoolIndex() ? 1 : $field->weight | CMD_INDEX_FLAG_CHECKSTEM;
                 $terms = $field->getCustomTokenizer()->getTokens($text, $doc);
                 foreach ($terms as $term) {
                     $term = strtolower($term);
                     $cmds[] = new XSCommand(CMD_DOC_TERM, $wdf, $field->vno, $term);
                 }
             }
         }
     }
     // submit cmd
     $cmds[] = new XSCommand(CMD_INDEX_SUBMIT);
     // execute cmd
     if ($this->_bufSize > 0) {
         $this->appendBuffer(implode('', $cmds));
     } else {
         for ($i = 0; $i < count($cmds) - 1; $i++) {
             $this->execCommand($cmds[$i]);
         }
         $this->execCommand($cmds[$i], CMD_OK_RQST_FINISHED);
     }
     // after submit
     $doc->afterSubmit($this);
     return $this;
 }