如果你希望 两个条件都必须满足 (即:user_id IN (...) AND project_id = "xxx"),那就不能使用 should ,而应该使用 must。
✅ 目标逻辑(SQL 等价):
sql
SELECT * FROM table
WHERE user_id IN ('u1', 'u2', 'u3')
AND project_id = 'some_project_id';
注意:这里假设
project_id是精确匹配 (不是全文搜索)。如果你确实要用全文搜索(比如模糊匹配),再用match;但通常 ID 类字段应做精确匹配,建议用term或terms。
✅ 推荐做法(两个都是精确匹配)
go
userIds := []interface{}{"u1", "u2", "u3"}
hardwareId := "hw_12345"
query := map[string]interface{}{
"query": map[string]interface{}{
"bool": map[string]interface{}{
"must": []map[string]interface{}{
// user_id IN (...)
{
"terms": map[string]interface{}{
"user_id": userIds,
},
},
// project_id = "hw_12345"(精确匹配)
{
"term": map[string]interface{}{
"project_id": hardwareId,
},
},
},
},
},
}
🔍 关键点说明:
| 条件 | 查询类型 | 适用场景 |
|---|---|---|
user_id IN (...) |
terms |
多个精确值匹配 |
project_id = "xxx" |
term |
单个精确值匹配 |
| 字段类型要求 | 必须是 keyword(不能是 text) |
否则无法精确匹配 |
⚠️ 如果
project_id在 mapping 中是text类型,你需要改用.keyword子字段,例如:
go"project_id.keyword": hardwareId
❌ 不要再用 should + minimum_should_match: 1
should表示"或"关系(满足其一即可)must表示"与"关系(全部必须满足)
🔄 如果你坚持用 match(不推荐用于 ID 字段)
仅当你确实需要全文分词匹配 时才用(比如 project_id 是一段描述文本):
go
{
"match": map[string]interface{}{
"project_id": "some text",
},
}
但对 ID、编码、设备号等结构化字段,强烈建议使用 term/terms + keyword 类型。
✅ 总结
要实现 两个条件都必须满足 ,使用 bool.must:
go
query := map[string]interface{}{
"query": map[string]interface{}{
"bool": map[string]interface{}{
"must": []interface{}{
map[string]interface{}{
"terms": map[string]interface{}{"user_id": []interface{}{"u1", "u2"}},
},
map[string]interface{}{
"term": map[string]interface{}{"project_id": "hw_123"},
},
},
},
},
}
这样就等价于 SQL 的 WHERE user_id IN (...) AND project_id = '...'。
