OK… I don’t want to confuse anyone with asking too many questions on the same ticket… But I have noticed something that I really don’t understand.
My atlas cluster is running 5.0.6 and when I use the query builder in atlas, there are differences.
The $lookup stage still has the from, foriegnField, localField, and as structure.
I can build the query using this syntax and when I put this in the get_movie(id) method 2 of the three tests pass.
this is the code I insert:
pipeline = [
{
'$match': {
'_id': ObjectId(id)
}
}, {
'$lookup': {
'from': 'comments',
'localField': '_id',
'foreignField': 'movie_id',
'as': 'comments'
}
}, {
'$sort': {'date': -1}
}
]
This give the following output.
(mflix) bossmandave@Davids-MacBook-Pro-2 mflix-python % pytest -m get_comments
============================================== test session starts ==============================================
platform darwin -- Python 3.8.12, pytest-3.3.0, py-1.8.0, pluggy-0.6.0
rootdir: /Users/bossmandave/Desktop/mflix-python, inifile: pytest.ini
plugins: flask-0.11.0
collected 43 items
tests/test_get_comments.py ..F [100%]
=================================================== FAILURES ====================================================
____________________________________ test_comments_should_be_sorted_by_date _____________________________________
client = <FlaskClient <Flask 'mflix.factory'>>
@pytest.mark.get_comments
def test_comments_should_be_sorted_by_date(client):
# in order from most to least recent
movie_ids = [
"573a1391f29313caabcd8414",
"573a1392f29313caabcd9d4f",
"573a1392f29313caabcdae3d",
"573a1392f29313caabcdb40b",
"573a1392f29313caabcdb585",
"573a1393f29313caabcdbe7c",
"573a1393f29313caabcdd6aa"
]
for id in movie_ids:
comments = get_movie(id).get('comments', [])
test_comments = sorted(
comments[:],
key=lambda c: c.get('date'),
reverse=True
)
for _ in range(0, min(10, len(comments))):
rand_int = randint(0, len(comments) - 1)
> assert comments[rand_int] == test_comments[rand_int]
E AssertionError: assert {'_id': Objec...cdbe7c'), ...} == {'_id': Object...cdbe7c'), ...}
E Omitting 1 identical items, use -vv to show
E Differing items:
E {'date': datetime.datetime(1999, 7, 11, 4, 8, 32)} != {'date': datetime.datetime(2007, 11, 4, 10, 12, 40)}
E {'email': 'joshua_kent@fakegmail.com'} != {'email': 'theresa_holmes@fakegmail.com'}
E {'_id': ObjectId('5a9427648b0beebeb695829c')} != {'_id': ObjectId('5a9427648b0beebeb6958340')}
E {'name': 'Joshua Kent'} != {'name': 'Theresa Holmes'}
E {'text': 'Aliquam cupiditate possimus impedit ab. Dolor neque eos est sunt nesciunt odit. Numquam mollitia est provident sunt doloribus. Totam magni quam ducimus.'} != {'text': 'Of...
E
E ...Full output truncated (2 lines hidden), use '-vv' to show
tests/test_get_comments.py:49: AssertionError
============================================== 40 tests deselected ==============================================
=============================== 1 failed, 2 passed, 40 deselected in 0.73 seconds ===============================
(mflix) bossmandave@Davids-MacBook-Pro-2 mflix-python %
Now when I change the query in the query builder to use the let stage, I get an output in atlas.
This is the query that works in atlas…(I had to replace id with a specific id)
[
{
'$match': {
'_id': ObjectId(id)
}
}, {
'$lookup': {
'from': 'comments',
'let': {'id': '$_id'},
'pipeline': [
{
'$match': {
'$expr': {'$eq': ['movie_id', '$$id']}
}
}
],
'as': 'comments'
}
}, {
'$sort': {
'date': -1
}
}
]
but when I run this in the program 2 of the three tests fail. This is the output from running pytest -m get_comnments with the new lookup.
(mflix) bossmandave@Davids-MacBook-Pro-2 mflix-python % pytest -m get_comments
============================================== test session starts ==============================================
platform darwin -- Python 3.8.12, pytest-3.3.0, py-1.8.0, pluggy-0.6.0
rootdir: /Users/bossmandave/Desktop/mflix-python, inifile: pytest.ini
plugins: flask-0.11.0
collected 43 items
tests/test_get_comments.py FF. [100%]
=================================================== FAILURES ====================================================
_________________________________________ test_fetch_comments_for_movie _________________________________________
client = <FlaskClient <Flask 'mflix.factory'>>
@pytest.mark.get_comments
def test_fetch_comments_for_movie(client):
# Lady and the Tramp
movie_id = "573a1394f29313caabcdfd61"
result = get_movie(movie_id)
> assert len(result.get('comments', [])) == 126
E AssertionError: assert 0 == 126
E + where 0 = len([])
E + where [] = <built-in method get of dict object at 0x10e961c00>('comments', [])
E + where <built-in method get of dict object at 0x10e961c00> = {'_id': ObjectId('573a1394f29313caabcdfd61'), 'awards': {'nominations': 1, 'text': 'Nominated for 1 BAFTA Film Award. ...1 nomination.', 'wins': 2}, 'cast': ['Peggy Lee', 'Larry Roberts', 'Bill Baucom', 'Verna Felton'], 'comments': [], ...}.get
tests/test_get_comments.py:17: AssertionError
_____________________________________ test_fetch_comments_for_another_movie _____________________________________
client = <FlaskClient <Flask 'mflix.factory'>>
@pytest.mark.get_comments
def test_fetch_comments_for_another_movie(client):
# 300
movie_id = "573a13b1f29313caabd36321"
result = get_movie(movie_id)
> assert len(result.get('comments', [])) == 145
E AssertionError: assert 0 == 145
E + where 0 = len([])
E + where [] = <built-in method get of dict object at 0x10e9e0f40>('comments', [])
E + where <built-in method get of dict object at 0x10e9e0f40> = {'_id': ObjectId('573a13b1f29313caabd36321'), 'awards': {'nominations': 37, 'text': '19 wins & 37 nominations.', 'wins': 19}, 'cast': ['Gerard Butler', 'Lena Headey', 'Dominic West', 'David Wenham'], 'comments': [], ...}.get
tests/test_get_comments.py:25: AssertionError
============================================== 40 tests deselected ==============================================
=============================== 2 failed, 1 passed, 40 deselected in 0.82 seconds ===============================
Not sure why this happens… If the query works using both methods… why does one pass more tests than the other?