Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix for item ids being required to be unique across all collections #26

Merged
merged 5 commits into from
Jul 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0/
- Add support for python 3.12. [#22](https://github.com/Healy-Hyperspatial/stac-fastapi-mongo/pull/22)
- Updated sfeos core to v3.0.0a0, fixed datetime functionality. [#23](https://github.com/Healy-Hyperspatial/stac-fastapi-mongo/pull/23)

### Fixed

- Added a new index based on collection id and item id to ensure item IDs aren't required to be unique across all collections. [#26](https://github.com/Healy-Hyperspatial/stac-fastapi-mongo/pull/26)


## [v3.2.1]

Expand Down
10 changes: 7 additions & 3 deletions stac_fastapi/mongo/database_logic.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ async def create_item_index():
collection = db[ITEMS_INDEX]
try:
await collection.create_index([("properties.datetime", -1)])
await collection.create_index([("id", 1)], unique=True)
await collection.create_index([("collection", 1), ("id", 1)], unique=True)
await collection.create_index([("geometry", "2dsphere")])
print(f"Indexes created successfully for collection: {ITEMS_INDEX}.")
except Exception as e:
Expand Down Expand Up @@ -691,7 +691,9 @@ async def prep_create_item(
mongo_item = self.item_serializer.stac_to_db(item, base_url)

if not exist_ok:
existing_item = await items_collection.find_one({"id": mongo_item["id"]})
existing_item = await items_collection.find_one(
{"collection": mongo_item["collection"], "id": mongo_item["id"]}
)
if existing_item:
raise ConflictError(
f"Item {mongo_item['id']} in collection {mongo_item['collection']} already exists"
Expand Down Expand Up @@ -733,7 +735,9 @@ def sync_prep_create_item(
mongo_item = self.item_serializer.stac_to_db(item, base_url)

if not exist_ok:
existing_item = items_collection.find_one({"id": mongo_item["id"]})
existing_item = items_collection.find_one(
{"collection": mongo_item["collection"], "id": mongo_item["id"]}
)
if existing_item:
raise ConflictError(
f"Item {mongo_item['id']} in collection {mongo_item['collection']} already exists"
Expand Down
28 changes: 28 additions & 0 deletions stac_fastapi/tests/resources/test_item.py
Original file line number Diff line number Diff line change
Expand Up @@ -890,3 +890,31 @@ async def test_search_datetime_validation_errors(app_client):
# resp = await app_client.get("/search?datetime={}".format(dt))
# assert resp.status_code == 400
# updated for same reason as sfeos


@pytest.mark.asyncio
async def test_create_same_item_in_different_collections(
app_client, ctx, load_test_data
):
"""Test creation of items and indices"""

test_item = load_test_data("test_item.json")
test_collection = load_test_data("test_collection.json")

# create item in collection where an item with same id already exists
resp = await app_client.post(
f"/collections/{test_collection['id']}/items", json=test_item
)
assert resp.status_code == 409, resp.json()

# prep second collection
test_collection["id"] = "test_collection2"
resp = await app_client.post("/collections", json=test_collection)
assert resp.status_code == 201, resp.json()

# create item with same id in second collection
test_item["collection"] = test_collection["id"]
resp = await app_client.post(
f"/collections/{test_collection['id']}/items", json=test_item
)
assert resp.status_code == 201, resp.json()