- 开发无止境 -
Data: 2023-01-16 23:42:18Form: JournalClick: 103
使用tp6的value()和column()查询遇到报错
Expected “projection” option to be array or object, string given
因为options里的projection是字符串,所以报错,改成数组
Call to undefined method think\db\connector\Mongo::query()
追溯到文件发现$this->query 是null
更新解决方法
最后发现是tp6用composer下载的mongodb库有问题,对比tp6自带的代码将图示位置改掉就好了
原本代码为
$options = $query->parseOptions();
if (isset($options['projection'])) {
$query->removeOption('projection');
}
if ($key && '*' != $field) {
$projection = $key . ',' . $field;
} else {
$projection = $field;
}
$query->setOption('projection', $projection);
if (!empty($options['cache'])) {
// 判断查询缓存
$cacheItem = $this->parseCache($query, $options['cache']);
$result = $this->getCacheData($cacheItem);
if (false !== $result) {
return $result;
}
}
$mongoQuery = $this->builder->select($query);
if (isset($options['projection'])) {
$query->setOption('projection', $options['projection']);
} else {
$query->removeOption('projection');
}
// 执行查询操作
$readPreference = $options['readPreference'] ?? null;
$resultSet = $this->query($options['table'], $mongoQuery, $readPreference);
修改后
$options = $query->parseOptions();
if (isset($options['projection'])) {
$query->removeOption('projection');
}
if (is_array($field)) {
$field = implode(',', $field);
}
if ($key && '*' != $field) {
$projection = $key . ',' . $field;
} else {
$projection = $field;
}
$query->field($projection);
if (!empty($options['cache'])) {
// 判断查询缓存
$cacheItem = $this->parseCache($query, $options['cache']);
$result = $this->getCacheData($cacheItem);
if (false !== $result) {
return $result;
}
}
$mongoQuery = $this->builder->select($query);
这个位置不可以直接强制把string类型的字段名直接转成数组。
//需要改成 $field => 1 的格式来查询 代表着只查询这个字段,
//同理 这里也可以 [$field1 => 1, $field2 => 1, $field3 => 1] 代表查询指定的三个字段
//或者 [$field => 0] 代表查询除$field外的所有字段
$query->setOption('projection', [$field => 1]);
**
转载自https://www.jianshu.com/p/151d20e32707
**
找到/vendor/topthink/think-mongo/src/builder/Mongo.php 这个文件
将multiAggregate方法 进行修改
/**
* 多聚合查询命令, 可以对多个字段进行 group by 操作
*
* @param Query $query 查询对象
* @param array $extra 指令和字段
* @return Command
*/
public function multiAggregate(Query $query, $extra)
{
$options = $query->getOptions();
list($aggregate, $groupBy) = $extra;
$groups = ['_id' => []];
foreach ($groupBy as $field) {
$groups['_id'][$field] = '$' . $field;
}
foreach ($aggregate as $fun => $field) {
$groups[$fun . '_' . $field] = ['$' . $fun => $field];
}
$pipeline = [
['$match' => (object) $this->parseWhere($query, $options['where'])],
['$group' => $groups],
];
$cmd = [
'aggregate' => $options['table'],
'allowDiskUse' => true,
'pipeline' => $pipeline,
'cursor' => new \stdClass,
];
foreach (['explain', 'collation', 'bypassDocumentValidation', 'readConcern'] as $option) {
if (isset($options[$option])) {
$cmd[$option] = $options[$option];
}
}
$command = new Command($cmd);
$this->log('group', $cmd);
return $command;
}
后续想了一下,这个写法 如果字段是int类型是没问题的 但是没法用sum:1来统计总数