MongoDB.live, free & fully virtual. June 9th - 10th. Register Now

Problem matching values in array

Hello, i was trying to do a array search using the query language however my db.collection.find() returns nothing this is my code:

from pymongo import MongoClient

client = MongoClient("mongodb://localhost:27017")
db = client.get_database('MapView')
neighborhood = db.bairroSP
restaurant= db.resSpec

search_restaurant = restaurant.find({'type':['meat','fish']})

for rest in search_restaurant:
    print(rest)

And here it’s the return:

C:\Users\André\AppData\Local\Programs\Python\Python37\python.exe
C:/Users/André/PycharmProjects/PythonDB/testes.py

Process finished with exit code 0

Here are some of the documents from my collection:

{"_id":1, “location”:{“coordinates”:[-46.665958,-23.563313] ,“type”:“Point”},“type”:[“fish”, “seafood],“preco”:39.25,“name”:“Barú Marisquería”}
{”_id":2, “location”:{“coordinates”:[-46.697364,-23.559586] ,“type”:“Point”},“type”:[ “fish”, “seafood”, “meat”],“preco”:30.00,“name”:“Costa Nova”}
{"_id":3, “location”:{“coordinates”:[-46.668611,-23.561079] ,“type”:“Point”},“type”:[“fish”, “seafood”, “meat”],“preco”:30.00,“name”:“Costa Nova”}

My objective is to get all documents with this both types of food in the array, doesn’t matter if they’re in the same array or in different arrays

Looks like a simple typo. You specified { tipo : …} in your find and you show document with a field named type.

sorry i missed this word when i was translating to make it easy to understand

The way you are writing find( t : [ a , b ] ) means look for an array t that is exactly [ a , b ]. What I understand is that you want all entries that have both a and b. Even [ b , a ] does not match.

Consider

> db.tipo.find( {} , { _id : 0 } )
{ "t" : [ "a", "b" ] }
{ "t" : [ "b", "a" ] }
{ "t" : [ "a", "b", "c" ] }
{ "t" : [ "a", "c" ] }
{ "t" : [ "b", "c" ] }
> db.tipo.find( { "t" : [ "a" , "b" ] } )
{ "_id" : ObjectId("5eb04706f36eaa9b112e3ca6"), "t" : [ "a", "b" ] }
> db.tipo.find( { "t" : "a" , t: "b" } )
{ "_id" : ObjectId("5eb04706f36eaa9b112e3ca6"), "t" : [ "a", "b" ] }
{ "_id" : ObjectId("5eb04706f36eaa9b112e3ca7"), "t" : [ "b", "a" ] }
{ "_id" : ObjectId("5eb04706f36eaa9b112e3ca8"), "t" : [ "a", "b", "c" ] }
{ "_id" : ObjectId("5eb047f6f36eaa9b112e3caa"), "t" : [ "b", "c" ] }

The last one is a little bit closer that what you want but have an extra that does not have a. One way to do it would be to do a setIntersection and match on the size. Another way could be with 2 match stage pipeline where you match a in the first one and match b on the second one. Probably an elemMatch of some sort could work but could not come up with a working one in a timely manner.

actually i made it work using the ‘$in’ operator, like this

search_restaurant = restaurant.find({'type':{'$in':['meat','fish']}})

thanks for your help

1 Like