我找到了解决方案,希望对可能面临同样问题的人有所帮助。
解决方案是将大列表拆分为多个较小的列表,并将每个列表放在单独的“术语”查询中。
例如,假设 max_terms_count 为 4,我们有 12 个项目需要从搜索结果中排除。
$iMaxTermsCount = 4;
$arItems = [
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
];
if (count($arItems) <= $iMaxTermsCount) {
// Add all items to the terms query. It will produce:
// "terms": {
// "item_id": [
// 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12
// ]
// }
} else {
$arChunks = array_chunk($arItems, $iMaxTermsCount);
foreach ($arChunks as $ar) {
// Add some (4) items to the terms query.
}
// The loop above will produce:
// {
// "terms": {
// "item_id": [
// 1, 2, 3, 4
// ]
// }
// },
// {
// "terms": {
// "item_id": [
// 5, 6, 7, 8
// ]
// }
// },
// {
// "terms": {
// "item_id": [
// 9, 10, 11, 12
// ]
// }
// }
}
最终的 JSON 对象会是这样的:
{
"query": {
"bool": {
"must_not": [
{
"bool": {
"should": [
{
"terms": {
"item_id": [
1, 2, 3, 4
]
}
},
{
"terms": {
"item_id": [
5, 6, 7, 8
]
}
},
{
"terms": {
"item_id": [
9, 10, 11, 12
]
}
}
]
}
}
]
}
}
}
上面的查询将排除所有项目而不会引发任何错误。