> **本文回答**：`svc.exprQueryFeature`（适用于**内存模式**打开的图，也可在几何模式用）语法、内置变量、示例。

## 一、何时用

- 内存模式打开时（没有空间库）→ 只能用表达式或 js 脚本查询。
- 几何模式也能用，但性能不如 SQL。

## 二、签名

```js
await svc.exprQueryFeature({
  expr: `return gInFeatureType == 'AcDbBlockReference'`,  // 或 C 语法（见下）
  fields: "objectid,blockname,envelop",
  useCache: true,
  limit: 1000000,       // 默认 100，要自己放大
  beginpos: 0,          // 分页
  geom: false
});
```

## 三、两种写法

### JavaScript 写法（推荐）

```js
expr: `return gInFeatureType == 'AcDbBlockReference' && gInLayerName == '建筑'`
```

### 表达式 C 风格写法（早期版本必需）

```js
expr: `gOutReturn := if((gInFeatureType == 'AcDbBlockReference' and gInLayerName == '建筑'), 1, 0);`
```

> 服务端判定语言的规则：表达式里**不含 `:=`**、或含 `return`、或含 `//js` → 按 JS 执行；否则按 C 风格（exprtk）编译。所以 `:=` 必须配 `and`/`or`（exprtk 不认 `&&`/`||`），JS 写法配 `&&`/`||` + `return`，两种语法不要混写。

## 四、内置变量（最常用）

| 变量 | 类型 | 说明 |
|---|---|---|
| `gInFeatureType` | string | 类名，如 `'AcDbLine'` |
| `gInLayerName` | string | 图层名 |
| `gInLayerIndex` | number | 图层索引 |
| `gInObjectId` | string | 实体 ID |
| `gInColor` | number | RGBA 整数 |
| `gInColorRed/Green/Blue/Alpha` | number | 分量 |
| `gInExtendMinX/Y/MaxX/Y` | number | 外包矩形 |
| `gInCoordX/Y/Z` | number[] | 坐标数组 |
| `gInCoordCount` | number | 坐标点数 |
| `gInAttrs1..s5` | string | 字符属性 1-5 |
| `gInAttrn6..n15` | number | 数值属性 6-15 |

`gOutReturn = 1` 加入结果集，`0` 不加入。

## 五、实体类型常用值

| 名 | 值 | 名 | 值 |
|---|---|---|---|
| AcDbLine | 1 | AcDbEllipse | 8 |
| AcDbPolyline | 2 | AcDbBlockReference | 10 |
| AcDb2dPolyline | 3 | AcDbHatch | 11 |
| AcDb3dPolyline | 4 | AcDbMText | 12 |
| AcDbSpline | 5 | AcDbText | 13 |
| AcDbArc | 6 | AcDbAttributeDefinition | 26 |
| AcDbCircle | 7 | AcDbAttribute | 27 |

## 六、典型示例

### 所有文字

```js
expr: `return (gInFeatureType == 'AcDbText' || gInFeatureType == 'AcDbMText' || gInFeatureType == 'AcDbAttributeDefinition' || gInFeatureType == 'AcDbAttribute')`
```

### 所有块参照

```js
expr: `return gInFeatureType == 'AcDbBlockReference'`
fields: `"objectid,blockname,layername,positon,rotate,scaleX,scaleY,scaleZ"`
```

### 长度为 10 的直线

```js
expr: `return (gInFeatureType == 'AcDbLine' && gInAttrn11 == 10)`
```

### 图层"网格线"中 x≥100 的多段线

```js
expr: `return (gInFeatureType == 'AcDbPolyline' && gInLayerName == '网格线' && gInExtendMinX >= 100)`
```

## 七、和 SQL 查询配合

查出所有块后，再用 SQL 查每个块下的子实体（块实体的几何数据要在空间库）：

```js
// 1) 先表达式找块
const blockQ = await svc.exprQueryFeature({
  expr: "return gInFeatureType == 'AcDbBlockReference'",
  fields: "objectid,blockname",
  limit: 1_000_000
});

// 2) 构造 SQL，objectid like 'xxx_%' 匹配块下子实体
const cond = blockQ.result
  .map(b => `objectid like '${b.objectid}_%'`)
  .join(" or ");

const subQ = await svc.conditionQueryFeature({
  condition: cond,
  fields: "objectid,area",
  limit: 100000
});
```

## 八、常见坑

1. **内存模式取不到真实几何** → 内存模式查询结果只给外包矩形（`isEnvelop:true`），真实 geojson 只能几何模式。注意 `geom` 参数是**路由开关**（true=几何渲染空间库、false=内存进程），不是"返回几何"开关。
2. **`gInAttrn11` 对应 SQL 的 `n6`**：在表达式里变量名是"第 11 个属性"，实际是数据库的 `n6`。易错。
3. **表达式太复杂 → 性能差**：尽量在 `fields` 里省掉不需要的字段；避免 `return true;` 扫全表。
4. **大量块 + 子实体组合查询** → 分页 + `like 'xxx_%'` 条件很长；可分批发起多次。
