title: How to correctly design a regular expression in pymongo?
body: <p>I use python 3.7.1 (default, Dec 14 2018, 19:28:38), and pymongo 3.7.2.</p>
  
  <p>In mongodb this works:</p>
  
  <pre><code>db.collection.find(
      {$and:[
      {"field":{$regex:"bon?"}},
      {"field":{$not:{$regex:"bon souple"}}},
      {"field":{$not:{$regex:"bon léger"}}}
      ]}
      )
  </code></pre>
  
  <p>So in pymongo I did the same as:</p>
  
  <pre><code>db.collection.find(
      {"$and":[
      {"field":{"$regex":"bon?"}},
      {"field":{"$not":{"$regex":"bon souple"}}},
      {"field":{"$not":{"$regex":"bon léger"}}}
      ]}
      )
  </code></pre>
  
  <p>but it indicates<code>pymongo.errors.OperationFailure: $regex has to be a string</code>.</p>
  
  <p>So I tried this as proposed <a href="https://stackoverflow.com/questions/13224753/mongodb-pymongo-how-to-escape-parameters-in-regex-search">here</a>:</p>
  
  <pre><code>liste_reg=[
  {'field': {'$regex': {'$not': re.compile('bon souple')}}}, 
  {'field': {'$regex': {'$not': re.compile('bon léger')}}}, 
  {'field': {'$regex': re.compile('bon?')}}
  ]
  rslt=list(
      db.collection.find({"$and":liste_reg})
  )
  </code></pre>
  
  <p>I noticed that even when there is no special character it indicates the same error:</p>
  
  <pre><code>liste_reg=[
  {'field': {'$regex': {'$not': re.compile('bon souple')}}} #where no special char is present
  ]
  rslt=list(
      db.collection.find({"$and":liste_reg})
  )
  </code></pre>
  
  <p>So I tried to use <code>"/"</code> as:</p>
  
  <pre><code>liste_reg=[
  {'field': {'$regex': {'$not':'/bon souple/'}}} #where no special char is present
  #even tried re.compile('/bon souple/')
  ]
  rslt=list(
      db.collection.find({"$and":liste_reg})
  )
  </code></pre>
  
  <p>the same error <code>pymongo.errors.OperationFailure: $regex has to be a string</code> still occurs.</p>
  
  <p>What can I do?</p>
  
  <p>SOME UPDATE OF MY RESEARCH OF SOLUTION</p>
  
  <p>the core of the issue seems to be with <code>$not</code> because when I do:</p>
  
  <pre><code>liste_reg=[{'field': {'$regex': 'bon?'}}]
  rslt=list(
      db.collection.find({"$and":liste_reg})
  )
  len(rslt)#gives 23 013, what is ok.
  </code></pre>
  
  <p>There is no error.</p>
  
  <p>SOME SAMPLES</p>
  
  <p>As asked by Emma I can give a sample, and it will explicit my request in mongo.
  Normally I must have these modalities in the field:</p>
  
  <ul>
  <li>sec</li>
  <li>très léger </li>
  <li>léger</li>
  <li>bon léger</li>
  <li>bon </li>
  <li>bon souple</li>
  <li>souple</li>
  <li>très souple</li>
  <li>collant</li>
  <li>lourd</li>
  <li>très Lourd</li>
  <li>profond</li>
  </ul>
  
  <p>The main problem for me is my spider did not parse correctly because I did not write a strong enough script for that.
  Instead of obtaining just "bon", I obtain this kind of result:</p>
  
  <pre><code>{"_id":"ID1",
  "field":"bon\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\t\tnon",
  ...}
  </code></pre>
  
  <p>and that's an example between many others wrong parsing.
  So that's why I want result that begins with <code>"bon?"</code> but not <code>"bon souple"</code> or <code>"bon léger"</code> because they have correct values, no <code>\n</code> or <code>\t</code>.</p>
  
  <p>So as samples:</p>
  
  <pre><code>[{"_id":"ID1",
  "field":"bon\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\t\tnon"},
  {"_id":"ID2",
  "field":"bon\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\tpremière"},
  {"_id":"ID3",
  "field":"bon\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\t2ème"},
  {"_id":"ID4",
  "field":"bon souple"},
  {"_id":"ID5",
  "field":"bon léger"}]
  </code></pre>