2015-06-10 20 views
7

Utworzono indeks elastycznego wyszukiwania, a moje bieżące mapowanie zapisuje kwotę w dolarach jako ciąg. To okazuje się trudne, ponieważ nie mogę poprawnie wyszukiwać/filtrować tej wartości.Jak przechowywać pieniądze w elasticsearch

GET catalog/product/_search 
{ 
    "filter": { 
    "range": { 
     "price": { 
     "from": 230.0, 
     "to": 300.0 
     } 
    } 
    } 
} 

Gdzie cena jest odwzorowana jako ciąg. Użyłem ciągu znaków, ponieważ przechodząc od wartości dziesiętnej w pythonie, miałem problemy, w których ta wartość nagle uzyskała wartości na poziomie 17,989999999999999999998789. Zdarza się to tylko czasami, ale nie chcę wchodzić w kwestię przejścia z dziesiętnego w pythonie do java double/float (więc po prostu str() rzecz).

Jakieś przemyślenia na temat lepszego podejścia? Czy powinienem ugryźć kulę i odwzorować cenę na podwójną lub zmienną?

+5

Problem polega na tym, że ElasticSearch nie ma typu "dziesiętnego", więc prawdopodobnie jest konwertowany na 'float'. Pomnożyć przez 100 i zapisać jako centy, a następnie przekonwertować stronę aplikacji? Cześć z dokładnością. –

+0

To świetny pomysł. Jeśli odpowiesz, mogę oznaczyć to jako takie. Jedynym problemem jest zwracanie dużej ilości danych, pętla nad wszystkimi tymi elementami może być kosztowna (wolna) strona aplikacji. Mógłbym użyć skryptu ES, ale to zbyt wolne, pomyślałem. – stincity

+1

Możesz również rzucić okiem na pierwszą odpowiedź na to pytanie http://stackoverflow.com/questions/1458633/how-to-deal-with-floating-point-number-precision-in-javascript – Val

Odpowiedz

7

Dzieje się tak dlatego ElasticSearch ma wbudowanego typu dla dziesiętnych lub waluty, więc wartość jest prawdopodobne jest przekształcany do float i cierpiącej z pływającymi kwestii precyzyjnych punktowych.

Powinieneś być w stanie obejść ten problem, po prostu przechowując wartość jako long (np. Liczbę centów zamiast dolarów) i konwertując do iz aplikacji decimal.

Ponieważ konwersję można przeprowadzać tylko dla wartości, które już są wyliczane, wpływ na wydajność powinien być nieistotny.

6

W nowszej wersji (sprawdzane 5,0), prawdopodobnie najlepszym rozwiązaniem jest użycie scaled_float z scaling_factor = 100 jak ich przykład:

PUT my_index 
{ 
    "mappings": { 
    "my_type": { 
     "properties": { 
     "number_of_bytes": { 
      "type": "integer" 
     }, 
     "time_in_seconds": { 
      "type": "float" 
     }, 
     "price": { 
      "type": "scaled_float", 
      "scaling_factor": 100 
     } 
     } 
    } 
    } 
} 

można znaleźć doc tutaj.

Powiązane problemy