preus de mercadona per zona: què canvia segons el codi postal

a catalunya, una ampolla de 2 litres de cola hacendado costa 1,10 €. a madrid o a sevilla, 0,80 €.
des del 14 de setembre tinc un programa que llegeix cada dia el preu de tots els productes de la botiga en línia de mercadona, zona per zona. el 6 d'octubre en va llegir 743.112, repartits en 174 zones, uns 4.270 per zona. és un projecte personal, sense cap relació amb mercadona.
què és una zona de mercadona
cada comanda de la botiga en línia la prepara un magatzem, i el magatzem decideix el catàleg i els preus. quan escrius el codi postal a la web, el servidor respon amb una capçalera, X-Customer-Wh, que diu quin magatzem et toca: bcn1, mad3, svq1 o un número.
per trobar-los tots, el programa pregunta per codis postals. els candidats surten de geonames, i en prova 300 al dia. va primer pel primer codi de cada província, després pel segon, i així el mapa cobreix tot el país aviat en lloc d'anar d'àlaba a saragossa. si la botiga respon 404, és que no hi reparteix, i no s'hi torna a preguntar fins al cap de 90 dies.
a la web i aquí en dic zona. per a l'anàlisi, cada zona rep la província que més es repeteix entre els seus codis postals. catalunya són les 21 zones de les províncies 08, 17, 25 i 43. canàries en té 17, i la península, 144.
el catàleg de mercadona en 6 consultes
la cerca de la botiga funciona amb algolia, i cada magatzem té un índex per idioma, com products_prod_bcn1_ca. el programa llegeix el català. una consulta buida torna 1.000 resultats com a molt, i un magatzem en té uns 4.300. per això mercapy, la llibreria de python que fa la feina, parteix el catàleg.
primer demana un sol resultat, amb el recompte de productes de cada categoria superior. després reparteix les categories, de la més grossa a la més petita, en grups que no passin de 1.000, i fa una consulta per grup amb un filtre OR. si un grup en torna més de 1.000, perquè els recomptes s'han mogut entre una consulta i l'altra, el parteix en dos. des de la versió 2.3.0, del 4 d'octubre, un magatzem surt en 6 peticions. abans en calien 27.
tres magatzems fallaven des del primer dia perquè el seu índex en català no té categories per filtrar. per a aquests, la llibreria parteix per franges d'un camp numèric de l'índex, score, i divideix per la meitat qualsevol franja que passi de 1.000.
al final, el programa compta els productes únics i els compara amb el total que declara algolia. si no quadren, la recollida queda com a degradada i no toca res. una recollida a mitges no pot fer desaparèixer cap producte, i perquè un producte deixi de constar en una zona hi ha de faltar dos dies seguits.
l'hora també compta. mercadona canvia els preus entre les 2 i les 4 de la matinada. dels 296 canvis nacionals que vaig poder datar, 272 van caure en aquesta franja, i per això el dia de recollida comença a les 5. abans, cada magatzem esperava 24 hores des de l'últim èxit. com que el cron passa cada dues hores, cada dia anava dues hores més tard, fins que en saltava un. fins al 4 d'octubre es van perdre així 147 de 2.141 dies de magatzem, un 7 %.
només es desa el que canvia
si copiés el catàleg sencer cada dia, a uns 1,6 kb per producte, serien més d'1 gb de json diari, quasi tot repetit.
el programa fa servir tres taules. product_state té una fila per producte i zona amb el preu d'ara. product_version només afegeix una fila quan el producte canvia en aquella zona. cada estat recorda també quina versió era vigent al final del dia anterior, i els canvis d'avui es calculen contra aquella.
el 5 d'octubre hi havia 820.298 versions, i la majoria deien el mateix, perquè un producte es llegeix igual a gairebé tots els magatzems. resums diferents, només 19.128. ara cada resum es desa un sol cop, en una taula on la clau és el hash del json, i les versions hi apunten. la taula de versions va passar d'1,6 gb a 172 mb, més 32 mb de resums. la base de dades sencera, de 2.096 mb a 735 mb.
abans vaig provar timescaledb, pg-xpatch, diferències cap endavant i cap enrere, i lz4. timescaledb ocupava menys, però perdia l'índex únic de versió oberta i la clau forana des de product_state. pg-xpatch va perdre files sense avisar en una còpia per lots.

quin preu es compara
un producte té diversos preus: el de prestatge, l'anterior si està rebaixat i el preu per quilo o per litre. els canvis en comparen un de sol, tracked_price.
als productes de mida fixa és el preu de prestatge. als de pes variable, com el peix o la carn al tall, és el preu per quilo. a les dades que vaig mirar per decidir-ho hi havia 370 productes de pes variable que es venien en dos magatzems o més. 156 tenien el mateix preu per quilo amb cistelles diferents, i només 3 tenien un preu per quilo diferent de debò. un lluç de 12,77 € a sevilla i de 17,14 € a barcelona val 11,50 €/kg als dos llocs. només canvia el pes del tall.
als productes de peixateria que es compren a pes, mercadona publica com a preu el preu per quilo multiplicat per la mida, o per 99 quan no hi ha mida. una gamba congelada era el producte més car de la base de dades, a 3.663 €. no tocava cap comparació, perquè aquests productes se segueixen pel preu per quilo, però la botiga mostra el preu d'un pas, de 0,15 a 0,4 kg, i ara el programa també.
les rebaixes van a part. l'api de mercadona té un camp que hauria de dir si un preu ha baixat, i en 397.000 estats desats no ha valgut mai true. el programa reconeix una rebaixa pel preu anterior ratllat al costat, i la desa com a reducció marcada. una baixada observada és un preu seguit més baix que el del final d'ahir, a la mateixa zona. si un dia hi ha dues recollides, els canvis es tornen a calcular contra la mateixa base, i dues recollides la mateixa tarda no poden fabricar una baixada i una pujada.
un sol preu a la península, menys a catalunya
dels 4.861 productes que es venien a almenys 20 zones peninsulars el 6 d'octubre, només 32 tenien preus diferents segons la zona. no arriba a l'1 %.
29 d'aquests 32 són begudes amb sucre: 8 mides de coca-cola, 3 de cola hacendado, 4 monster, 2 red bull, 6 batuts i begudes de llet hacendado, l'energètica hacendado, 2 preparats lactis amb cereals, l'orxata i 2 tòniques hacendado. totes costen més a les 21 zones catalanes i a cap altra. les versions zero tenen el mateix preu a tot arreu.

és l'impost català sobre les begudes ensucrades envasades, que és de 0,10 € per litre si la beguda té entre 5 i 8 grams de sucre per 100 ml, i de 0,15 € si en té més. a la cola hacendado de 2 litres, la diferència és de 0,30 €, justament 0,15 € per litre. a la coca-cola de 2 litres és de 0,37 €, i al monster de mig litre, de 0,10 €. aquestes ja no surten tan rodones.
dels 32, els altres 3 són dos productes de llimona i les pits de pollastre sencers congelats.
canàries, la fruita més cara
hi ha 82 productes de fruita i verdura que es venen a canàries i a almenys 20 zones peninsulars. comparant la mediana de cada lloc, 64 hi són més cars i 5, més barats. el bròquil val 5,80 €/kg a les 17 zones canàries, igual des del 14 de setembre, i 2,70 €/kg a les altres 157.
tres setmanes, i gairebé tot puja
vaig agafar les 71 zones amb una recollida completa el 14 de setembre i el 6 d'octubre. em vaig quedar amb 3.526 productes venuts per unitat, els que es venen a almenys 30 d'aquestes zones i no tenien cap preu ratllat cap dels dos dies. un producte compta com a pujada si ha pujat a la majoria de les seves zones.
90 han pujat. 2 han baixat, la llet semidesnatada i la desnatada hacendado, d'1 cèntim cadascuna i a les 71 zones. cap dels 92 ha canviat de mida.
el número depèn del dia d'inici. si començo a comptar el 15 o el 16 de setembre, les pujades són 78 i 59. les baixades continuen sent les mateixes 2.

la fruita de temporada va més de pressa. el 14 de setembre, el meló pell de granota valia 0,70 €/kg a la península. el 21 va passar a 0,90, el 29 a 1,35 i el 6 d'octubre a 2,20, a les 144 zones peninsulars.
el que encara falta
la web que ho ensenyarà, en català, encara no és pública. hi posaràs el codi postal i veuràs el preu de cada producte a la teva zona i com ha canviat des del 14 de setembre.
tot això surt de tres setmanes de dades. la idea és deixar el programa recollint cada dia durant anys, i la recollida és el primer que vaig fer perquè un preu que avui no es llegeix ja no es pot recuperar.