Chapter 1: Ticket : Projection error

I am gegting the following erros while runnig the pytest -m projection. Runnig the mongo compass for coutntires = ‘Kosova’ the result is 0 and for [‘Russia’,‘Japan’] it is only 2 records

@pytest.mark.projection
def test_basic_country_search_db(client):
countries = [‘Kosovo’]
result = get_movies_by_country(countries)

  assert len(result) == 2

E assert 0 == 2
E + where 0 = len()

and

@pytest.mark.projection
def test_basic_country_search_shape_db(client):
countries = [‘Russia’, ‘Japan’]
result = get_movies_by_country(countries)

  assert len(result) == 2241

E AssertionError: assert 2 == 2241
E + where 2 = len([{’_id’: ObjectId(‘573a139af29313caabcf14fa’), ‘title’: ‘Vostochnaya elegiya’}, {’_id’: ObjectId(‘573a13baf29313caabd51faa’), ‘title’: ‘My Love’}])

AFter running python run.py

clicking on status the connection works fine , however the Projection returns below.

Projection: The return from the api was incorrect when searching by country

1 Like

am also getting error when running the ticket: projection.

Am a bit confussed on how to run this session.

  1. where to modify in the db.py file.
  2. I already ran the area on script test_projection so it’s thowing errors on that.

Can someone direct me on where exactly to modify in db.py and if anything else needs to be done.

Am being delayed just here to complete the assignment.
Any help is so much appreciated.
Regards
Paulnewman

@Mohandas_33264
I ran into this issue too, because I didn’t quite understand the question. We’re supposed to search for all films created in any of the listed countries. There’s more than one way to compare arrays and the results you are getting tell you that your search query is too restrictive:

  • get_movies_by_country([‘Kosovo’]) wants to have 2 results, but you’re not finding any
  • similarly for [‘Russia’, ‘Japan’] we should be getting 2241 matching results

@PaulNewman
If you haven’t found it, the Task header in Ticket: Projection should tell you which method you need to edit in db.py. Once you’ve found the method, there should be a TODO comment explaining what needs to be done.

1 Like

@n-Holmes
Thanks for your response.

I located the method def get_movies_by_country(countries):
then modified this section return list(db.movies.find())
as below

    return list(db.movies.find({"countries": {$in: ["Italy","France","UK"]},{"title" : 1,"_id" : 1}}))

but when i ran it, it’s not running.

getting this error:
C:\university\m220\mflix-python>pytest -m projection
ImportError while loading conftest ‘C:\university\m220\mflix-python\tests\conftest.py’.
tests\conftest.py:2: in
from mflix.factory import create_app
mflix\factory.py:12: in
from mflix.api.movies import movies_api_v1
mflix\api\movies.py:2: in
from mflix.db import get_movie, get_movies, get_movies_by_country,
E File “C:\university\m220\mflix-python\mflix\db.py”, line 79
E return list(db.movies.find({“countries”: {$in: [“Italy”,“France”,“UK”]},{“title” : 1,"_id" : 1}}))
E ^
E SyntaxError: invalid syntax

C:\university\m220\mflix-python>

I know there is something am not doing correctly or i have not started but i can’t figure it out.
Am short of idea of what to do next.

Can you guide me.

Thanks

1 Like

You’re almost there, just looks like you’re having a little bracket/parenthesis trouble.

If you look in the pymongo collection documentation here: http://api.mongodb.com/python/current/api/pymongo/collection.html for the find method, you should see it takes a bunch of different arguments. For our purposes though, we only really care about the first two: filter and projection, but currently you’re only passing a single object into find (the outer curly braces).

The reason you’re getting a SyntaxError, instead of just a bad result, is because the bit before the comma looks like a dict (with key: value pairs) and the bit after the comma looks like a set (just a value), so the python parser doesn’t know what to do with it.

1 Like

Hello PaulNewman,

Thanks for the note, I’m sorry you encountered this issue. Have you tried wrapping $in in quotation marks?

Matt

1 Like

Hi Paul,

I just tried this and passed Ticket : Projection

Try this code in the db.py and function def get_movies_by_country(countries):

return list(db.movies.find({“countries”: {"$in": countries}},{“title”:1}))

5 Likes

@Mohandas_33264
thanks for the correction, i have seen where i’ve been making mistake.
I did not enclose the $in aggregation in quotation mark.

Thanks for the assistance,mine has passed.
Regards
Paulnewman

@mattjavaly
Thanks for the correction. i did wrapped the $in aggregation in quotation mark and it passed.

Am so happy now for moving on with the course.

Regards
Paulnewman

1 Like

Thanks it worked. I was not able to follow how the course is designed.
This problem gave me a good understanding of design and to resolve issue.

Careful Paul (and other students). Why would you hard-code the queries submitted by the testing-script? What if an end-user wants to search for movies from the USA, or Germany? So while the query is almost there, you’ll need to find a way to make it generic for any possible query.

Hi Mohandas_33284,

This return list works in running “pytest run.py”… but while testing it in my shell (MongoDB Enterprise mflix-shard-0:PRIMARY>) I get the error message “E QUERY [js] ReferenceError: countries is not defined”… I’ve been working on this the whole day. But many thanks for your help, I can now move to the next ticket.

when I execute pytest - m projection
with return list(db.movies.find({“countries”: {"$in": [“countries”]}},{“title” : 1, “_id” : 1}))
I getting the following errors…

================================== FAILURES ===================================
________________________ test_basic_country_search_db _________________________

client = <FlaskClient <Flask ‘mflix.factory’>>

@pytest.mark.projection
def test_basic_country_search_db(client):
    countries = ['Kosovo']
    result = get_movies_by_country(countries)
  assert len(result) == 2

E TypeError: object of type ‘ServerSelectionTimeoutError’ has no len()

tests\test_projection.py:15: TypeError
_____________________ test_basic_country_search_shape_db ______________________

client = <FlaskClient <Flask ‘mflix.factory’>>

@pytest.mark.projection
def test_basic_country_search_shape_db(client):
    countries = ['Russia', 'Japan']
    result = get_movies_by_country(countries)
  assert len(result) == 2421

E TypeError: object of type ‘ServerSelectionTimeoutError’ has no len()

tests\test_projection.py:22: TypeError
============================= 41 tests deselected =============================
================== 2 failed, 41 deselected in 60.71 seconds ===================

@barrington, please don’t post potential answer to the lab.

You get an error because your match criteria is wrong. When you put a value in quotes like "countries", you get the string countries, you are not accessing the variable countries.

I don’t understand how you guys past the test. I’m using the exaxt same thing

db.movies.find({“countries”: {"$in": countries}},{“title”:1}) and I still get an assertion error. This test makes no sense to me.

We cannot help you if you do not post the assertion error you are getting.

Not sure where to start. I was able to connect to app and do a test connection that passed thru the terminal yesterday. Now I can’t.

Browser says I’m connected but the terminal fails the connection test. This worked yesterday and now nothing. Not sure what happened.

The only change of the function ‘get_movies_by_country(countries)’ is the return line:

    return list(db.movies.find({"countries": {"$in":countries}},{"title":1,"_id":1})

m220-test.pdf (134.4 KB)

It looks like you are trying to connect to localhost in test.

It should work if you have mongod running locally. If not, use the same URI for test as the one you have in prod.