Property/Data Clean Up - Script for Deleted Properties

MLS ↔ ElasticSearch Reconciliation

Command: php artisan job:mls-es-reconcile

Scans ElasticSearch listings for a feed and removes records that no longer exist in the source MLS. For each ES record, it checks the MLS API — if the listing is gone, the ES document is deleted from both the primary and secondary collections.

ℹ️ Properties are occasionally deleted from the RESO feed due to MLS maintenance or app modifications. Run this command when a deleted property is found to check for additional stale records.


Options

Option Required Default Description
--modification_timestamp_from Yes * Start of the MLSModificationTimestamp window (inclusive). Format: "2026-03-01 00:00:00"
--modification_timestamp_to Yes * End of the window (inclusive). Same format.
--feeds No all feeds Comma-separated feed names: actriswacomfrmls
--dry-run No true Log only — no deletes. Pass false  to actually delete.
--status No all Comma-separated StandardStatus values to narrow the scan. E.g. active,closed
--index No primary Which collection to scan: primary  or secondary . (Deletes always hit both.)
--limit No none Max records per feed. Handy for testing.
--listing_key No Reconcile a single record by its ES _id  (ListingKey). Skips the timestamp requirement.

* Timestamps are required for full scans. Not required when using --listing_key .


Examples

Dry run — preview stale records in a date window
php artisan job:mls-es-reconcile \
  --feeds=actris \
  --modification_timestamp_from="2026-03-01 00:00:00" \
  --modification_timestamp_to="2026-03-18 19:19:31"
Actually delete stale records for two feeds
php artisan job:mls-es-reconcile \
  --dry-run=false \
  --feeds=actris,waco \
  --modification_timestamp_from="2026-03-01 00:00:00" \
  --modification_timestamp_to="2026-03-18 19:19:31"
Check a single listing (no timestamp needed)
php artisan job:mls-es-reconcile --feeds=actris --listing_key=ABC123

Important Notes

⚠️ Always dry-run first. --dry-run=false  permanently deletes ES documents. There is no undo.

🕐 Keep the timestamp window narrow. The window limits MLS API calls and avoids rate limits. Use the smallest range that covers the affected period.

🛡️ Safe on failures. If the MLS or ES API fails, the command retries, then aborts the entire run rather than deleting records it couldn't confirm. The team is alerted on Slack in production.

📋 Logs are written under the mls_es_reconcileslug, including per-feed and total counts of records fetched, stale, and deleted.

Did this answer your question? Thanks for the feedback There was a problem submitting your feedback. Please try again later.