PyMongo中基于字段值长度的集合查询及$strLenCP报错问题
Hey there, let's break down why your query is throwing that OperationFailure: $strLenCP requires a string argument, found: null error, and how to fix it.
The Root Cause
Your $and query uses $strLenCP on text, text2, and text3 fields, but this operator only works on string values. When you run limit(2), you're lucky enough to hit documents where all those fields are valid strings. But once you go beyond 2, your query encounters a document where at least one of those fields is null, doesn't exist, or isn't a string—causing the error.
Solution 1: Only Include Documents with String Fields
If you want to filter only documents where text, text2, and text3 are actual strings (and their lengths are <5), add a $type check to each condition. This ensures $strLenCP only runs on valid string inputs:
{ "$and": [ { "$and": [ {"text": {"$type": "string"}}, {"$expr": {"$lt": [{"$strLenCP": "$text"}, 5]}} ] }, { "$and": [ {"text2": {"$type": "string"}}, {"$expr": {"$lt": [{"$strLenCP": "$text2"}, 5]}} ] }, { "$and": [ {"text3": {"$type": "string"}}, {"$expr": {"$lt": [{"$strLenCP": "$text3"}, 5]}} ] } ] }
Solution 2: Handle Null/Non-String Fields as "Valid" (Length <5)
If you want to treat null, missing fields, or non-string values as satisfying the "length <5" condition (since they don't have a long string), use one of these approaches:
Option A: Using $ifNull (Simpler)
This converts any null or missing field to an empty string (length 0, which is <5):
{ "$and": [ {"$expr": {"$lt": [{"$strLenCP": {"$ifNull": ["$text", ""]}}, 5]}}, {"$expr": {"$lt": [{"$strLenCP": {"$ifNull": ["$text2", ""]}}, 5]}}, {"$expr": {"$lt": [{"$strLenCP": {"$ifNull": ["$text3", ""]}}, 5]}} ] }
Option B: Using $cond (More Explicit)
This checks if the field is a string first—if yes, calculate its length; if not, return 0 (which is <5):
{ "$and": [ {"$expr": { "$lt": [ {"$cond": [{"$eq": [{"$type": "$text"}, "string"]}, {"$strLenCP": "$text"}, 0]}, 5 ] }}, {"$expr": { "$lt": [ {"$cond": [{"$eq": [{"$type": "$text2"}, "string"]}, {"$strLenCP": "$text2"}, 0]}, 5 ] }}, {"$expr": { "$lt": [ {"$cond": [{"$eq": [{"$type": "$text3"}, "string"]}, {"$strLenCP": "$text3"}, 0]}, 5 ] }} ] }
Which Solution Should You Pick?
- Use Solution 1 if you only care about documents where all three fields exist and are strings.
- Use Solution 2 if you want to include documents with null/missing/non-string fields (since they don't meet the "length ≥5" criteria you originally filtered out).
内容的提问来源于stack exchange,提问作者Deshwal

