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: actris , waco , mfrmls |
| --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
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"
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"
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.