As I said before, you need another layer of encoding/decoding, e.g. JSON. (Unless you plan on using Redis hash maps directly? They only support byte keys and values.) Your example looks like Javascript or Python, but I don't know where you got it. Neither Clojure nor Java will print a map-like native structure in that format! I'll assume you are dealing with JSON.
To write: native data structure -> JSON string -> UTF-8 bytes -> Redis SET To read: Redis GET -> UTF-8 bytes -> JSON string -> native data structure. Example with carmine in Clojure: user=> (require '[taoensso.carmine :as car] '[cheshire.core :refer [generate -string parse-string]]) nil user=> (defn json-set [k v] (car/set k (car/raw (.getBytes (generate-string v) "UTF-8")))) #'user/json-set user=> (defn json-get [k] (car/parse #(parse-string %) (car/get k))) #'user/json-get user=> (def conn {:pool {} :spec {}}) #'user/conn user=> (def test-data { "money" "100000", "contact_name" "Martha Vena"}) #'user/test-data user=> (car/wcar conn (json-set "test" test-data)) "OK" user=> (car/wcar conn (json-get "test")) {"contact_name" "Martha Vena", "money" "100000"} redis-clj: 127.0.0.1:6379> get test "{\"contact_name\":\"Martha Vena\",\"money\":\"100000\"}" Here's an example with a smiley face to test the UTF-8 encoding: user=> (car/wcar conn (json-set "test2" ["☺"])) "OK" user=> (car/wcar conn (json-get "test2")) ["☺"] user=> (count (first *1)) 1 In redis-cli: 127.0.0.1:6379> get test2 "[\"\xe2\x98\xba\"]" On Wednesday, July 15, 2015 at 11:43:08 AM UTC-5, gingers...@gmail.com wrote: > > Sorry, I am stupid. I misunderstood the problem entirely. Escaped quote > marks are never really the problem. The real issue is that this works for > us: > > { "money" : "100000", "contact_name" : "Martha Vena" } > > and this doesn't work for us: > > "{ \"money\" : \"100000\", \"contact_name\" : \"Martha Vena\" }" > > but in the second case the whole thing is a string. In the first case I > suppose the structure is a hashmap. I'll look at Carmine to see if it can > help me get the hashmap structure consistently. > > > > On Friday, July 10, 2015 at 6:04:01 PM UTC-4, gingers...@gmail.com wrote: >> >> >> Hmm, well, I am grateful to you for running such a detailed test, and I >> should have tested this myself: >> >> >The actual bytes stored at the "test" key are 0x61 0x22 0x62 >> >> However, something in our code fails when the quote marks are escaped, >> but everything works the way we expect when the quote marks do not appear >> to be escaped. I amazed by this: >> >> user=> (count *1) >> 3 >> >> Perhaps the error is something entirely different from what I was >> assuming. >> >> >> >> >> >> On Thursday, July 9, 2015 at 7:52:54 PM UTC-4, Francis Avila wrote: >>> >>> This is what I am doing with Carmine and it seems to work properly. >>> >>> First some setup in the repl: >>> >>> user=>(require '[taoensso.carmine :as car]) >>> nil >>> user=> (def conn {:pool {} :spec {}}) >>> #'user/conn >>> user=> (defn raw-str-set [k ^String v] (car/set k (car/raw (.getBytes v >>> "UTF-8")))) >>> #'user/raw-str-set >>> user=> (defn raw-str-get [k] (car/parse (car/get k) #(String. ^bytes % >>> "UTF-8"))) >>> #'user/raw-str-get >>> >>> >>> Now I save a test string: >>> >>> user=> (car/wcar conn (raw-str-set "test" "a\"b")) >>> "OK" >>> >>> In a redis-cli terminal: >>> >>> $ redis-cli >>> 127.0.0.1:6379> get "test" >>> "a\"b" >>> 127.0.0.1:6379> >>> >>> The escaped \" you see in redis-cli is just for printing. The actual >>> bytes stored at the "test" key are 0x61 0x22 0x62 >>> >>> Now lets pull this out of redis with Carmine: >>> >>> >>> user=> (car/wcar conn (raw-str-get "test")) >>> "a\"b" >>> user=> (count *1) >>> 3 >>> >>> As you can see, we round-tripped without any strange extra escaping. >>> >>> Probably your java app can just use Jedis client.get("test") and >>> client.set("test","a-string"), since I think it does UTF-8 encode and >>> decode of strings and no other serialization. >>> >>> >>> You still need to use JSON on top of this so you can get richer data >>> structures instead of just strings. >>> >>> On Thursday, July 9, 2015 at 4:18:51 PM UTC-5, gingers...@gmail.com >>> wrote: >>>> >>>> I am sorry, I should have explained this sooner. When I do this: >>>> >>>> (.getBytes document-as-string "UTF-8") >>>> >>>> The quote marks are always escaped. When I do this: >>>> >>>> document-as-byte-array (bytes (byte-array (map (comp byte int) >>>> document-as-string))) >>>> >>>> The quote marks are sometimes escaped, but most of the time they are >>>> not. >>>> >>>> I need to avoid having those quote marks escaped. I am not clear what >>>> is causing the escaping. >>>> >>>> >>>> >>>> >>>> On Thursday, July 9, 2015 at 12:01:51 PM UTC-4, Francis Avila wrote: >>>>> >>>>> your document-as-byte-array is wrong--it only handles ascii, and very >>>>> inefficiently too. >>>>> >>>>> Just say (.getBytes document-as-string "UTF-8") to get a utf-8 >>>>> encoding of the string as a byte array. >>>>> >>>>> On Thu, Jul 9, 2015 at 10:41 AM, <gingers...@gmail.com> wrote: >>>>> >>>>>> >>>>>> > As for the escaped quotes, you may be using pr or prn to print, or >>>>>> maybe you are >>>>>> > using pr-str to produce the string representation. I can't be sure. >>>>>> >>>>>> At the moment I create the string like this: >>>>>> >>>>>> document-as-string (str "{\"transaction-id\" : \"" >>>>>> transaction-id "\", \"message\" : \"" message "\"}") >>>>>> document-as-byte-array (bytes (byte-array (map (comp byte >>>>>> int) document-as-string))) >>>>>> >>>>>> The crazy thing is that this sometimes works, but other times the >>>>>> quote marks appear in Redis as escaped quote marks. As near as I can >>>>>> tell, >>>>>> the important factor is the length of the string. A short string is >>>>>> likely >>>>>> to have its quote marks escaped. A long string does not have its quote >>>>>> marks escaped. >>>>>> >>>>>> My co-worker is working on the Java app. I am working on the Clojure >>>>>> app. We can both adjust out apps freely, just so long as we can get data >>>>>> to >>>>>> and from each other, in a manner that allows us to eventually cast the >>>>>> data >>>>>> to and from JSON. >>>>>> >>>>>> Any suggestions are welcome. >>>>>> >>>>>> >>>>>> >>>>>> >>>>>> >>>>>> >>>>>> On Wednesday, July 8, 2015 at 8:58:53 PM UTC-4, Francis Avila wrote: >>>>>>> >>>>>>> Who is saving these strings, and who is reading them? Do you have >>>>>>> complete control over both apps, or does one of them need to be aligned >>>>>>> with the other? >>>>>>> >>>>>>> If the Java app is the baseline, you need to know the exact details >>>>>>> of the format of the data it saves. Just knowing "it's JSON" is not >>>>>>> enough, >>>>>>> because there may be other data types (e.g. dates) that don't have >>>>>>> native >>>>>>> JSON representations. (The go-to JSON de/encoder for clojure is >>>>>>> cheshire: >>>>>>> https://github.com/dakrone/cheshire ) >>>>>>> >>>>>>> I took a quick look at Jedis and the easy, default way of using it >>>>>>> is with strings. It will encode strings to UTF-8 before sending to >>>>>>> Redis >>>>>>> and decode from UTF-8 on read. You can set raw byte arrays too (which >>>>>>> will >>>>>>> not be altered in any way before sending), but it's not clear to me how >>>>>>> it >>>>>>> can read out raw byte arrays. (I'm sure there's a way, but it's not >>>>>>> immediately obvious.) >>>>>>> >>>>>>> As for the escaped quotes, you may be using pr or prn to print, or >>>>>>> maybe you are using pr-str to produce the string representation. I >>>>>>> can't be >>>>>>> sure. >>>>>>> >>>>>>> On Wednesday, July 8, 2015 at 5:31:27 PM UTC-5, gingers...@gmail.com >>>>>>> wrote: >>>>>>>> >>>>>>>> And I have another stupid question. Using the above code, I am >>>>>>>> sometimes getting strings in Redis that have escaped quotation marks, >>>>>>>> like >>>>>>>> this: >>>>>>>> >>>>>>>> " \"transaction-id\" : \" 1ec47c2e-21ee-427c-841c-80a0f89f55d7 \" >>>>>>>> \"debrief\" : \" Susan Hilly at Citi called to get a quotation for >>>>>>>> discounted weekly car rental for approximately 3 cars per week, or 150 >>>>>>>> rentals annually. \" " >>>>>>>> >>>>>>>> Why is that happening? >>>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> On Wednesday, July 8, 2015 at 5:38:20 PM UTC-4, >>>>>>>> gingers...@gmail.com wrote: >>>>>>>>> >>>>>>>>> Francis Avila, >>>>>>>>> >>>>>>>>> Thank you for your response. The Java app is using Jedis and the >>>>>>>>> Clojure app is using Carmine. I'm wondering if you can suggest what >>>>>>>>> you >>>>>>>>> think would be the easiest way to allow these 2 apps to understand >>>>>>>>> each >>>>>>>>> other's strings? >>>>>>>>> >>>>>>>>> You were correct about how unsafe the above code was. I tested it >>>>>>>>> for less than 15 minutes and ran into the fact that a \n newline made >>>>>>>>> a >>>>>>>>> mess of everything. >>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> On Wednesday, July 8, 2015 at 5:15:35 PM UTC-4, Francis Avila >>>>>>>>> wrote: >>>>>>>>>> >>>>>>>>>> You are running into Carmine's automatic nippy serialization. >>>>>>>>>> https://github.com/ptaoussanis/carmine#serialization >>>>>>>>>> >>>>>>>>>> Redis only stores byte arrays (what it calls "strings"). Carmine >>>>>>>>>> uses the nippy library (the meaning of "NPY" in your byte stream) to >>>>>>>>>> represent rich types compactly as bytes. >>>>>>>>>> https://github.com/ptaoussanis/nippy >>>>>>>>>> >>>>>>>>>> If you give Carmine a byte array to store, it will store it >>>>>>>>>> directly without nippy-encoding it. E.g. (.getBytes "{}" "UTF-8") >>>>>>>>>> >>>>>>>>>> BTW your document-as-string example is extremely unsafe: how will >>>>>>>>>> you reliably read this message out again? e.g. what if the 'debrief' >>>>>>>>>> string >>>>>>>>>> contains a single quote? Use a proper serialization format. >>>>>>>>>> >>>>>>>>>> So the key is to have both your Clojure and Java app store >>>>>>>>>> *bytes* in Redis using the same serialization. You can store >>>>>>>>>> anything you >>>>>>>>>> want (nippy, utf-8-encoded json, fressian, bson, utf-8 xml, utf-16 >>>>>>>>>> java >>>>>>>>>> strings, whatever) as long as it's bytes and it's read and written >>>>>>>>>> the same >>>>>>>>>> way in all your apps. >>>>>>>>>> >>>>>>>>>> The Redis library your Java app is using may have its own >>>>>>>>>> automatic de/serialization, too. You need to find out what it's >>>>>>>>>> doing and >>>>>>>>>> either work with this or turn it off, just like with Carmine. >>>>>>>>>> >>>>>>>>>> Nippy unfortunately does not have a Java API out of the box: >>>>>>>>>> https://github.com/ptaoussanis/nippy/issues/66 >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> On Wednesday, July 8, 2015 at 3:35:49 PM UTC-5, >>>>>>>>>> gingers...@gmail.com wrote: >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> I am not sure if this is a Clojure question or a Java question. >>>>>>>>>>> I don't know Java, so I could use whatever help folks can offer. >>>>>>>>>>> >>>>>>>>>>> "primitive string" here means what I can write when I am at the >>>>>>>>>>> terminal. >>>>>>>>>>> >>>>>>>>>>> We have 2 apps, one in Clojure, one in Java. They talk to each >>>>>>>>>>> other via Redis. I know the Java app can read stuff out of Redis, >>>>>>>>>>> using our >>>>>>>>>>> "transaction-id", if I use the terminal and open up "redis-clj" and >>>>>>>>>>> write a >>>>>>>>>>> string directly from the terminal. But I have this Clojure code, >>>>>>>>>>> which >>>>>>>>>>> depends on Peter Taoussanis's Carmine library: >>>>>>>>>>> (defn worker [document] >>>>>>>>>>> {:pre [(string? (:transaction-id document))]} >>>>>>>>>>> (let [transaction-id (:transaction-id document) >>>>>>>>>>> document-as-string (str "{'transaction-id' : '" >>>>>>>>>>> transaction-id "', 'debrief' : '" (:debrief document) "'}" ) >>>>>>>>>>> redis-connection {:pool {} :spec {:host "127.0.0.1" >>>>>>>>>>> :port 6379 }}] >>>>>>>>>>> (timbre/log :trace " message we will send to NLP " >>>>>>>>>>> document-as-string) >>>>>>>>>>> (carmine/wcar redis-connection (carmine/set transaction-id >>>>>>>>>>> document)) >>>>>>>>>>> (loop [document-in-redis (carmine/wcar redis-connection >>>>>>>>>>> (carmine/get transaction-id))] >>>>>>>>>>> >>>>>>>>>>> (if-not (.contains (first document-in-redis) "processed") >>>>>>>>>>> (recur (carmine/wcar redis-connection (carmine/get >>>>>>>>>>> transaction-id))) >>>>>>>>>>> (do >>>>>>>>>>> (carmine/wcar redis-connection (carmine/del >>>>>>>>>>> transaction-id)) >>>>>>>>>>> document-in-redis))))) >>>>>>>>>>> >>>>>>>>>>> This line in particular, I have tried doing this several ways: >>>>>>>>>>> >>>>>>>>>>> document-as-string (str "{'transaction-id' : '" >>>>>>>>>>> transaction-id "', 'debrief' : '" (:debrief document) "'}" ) >>>>>>>>>>> >>>>>>>>>>> In Redis, I expect to see: >>>>>>>>>>> >>>>>>>>>>> {'transaction-id' : '42e574e7-3b80-424a-b9ff-01072f1e0358', >>>>>>>>>>> 'debrief' : 'Smeek Hallie of Withers, Smeg, Harrington and Norvig >>>>>>>>>>> responded >>>>>>>>>>> to our proposal and said his company is read to move forward. The >>>>>>>>>>> rate of >>>>>>>>>>> $400 per ton of shredded paper was acceptable to them, and they >>>>>>>>>>> shred about >>>>>>>>>>> 2 tons of documents every month. $96,000 in potential revenue >>>>>>>>>>> annually. I >>>>>>>>>>> will meet with him tomorrow and we will sign the contract.'} >>>>>>>>>>> >>>>>>>>>>> But if I then launch redis-cli, I see: >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> 127.0.0.1:6379> keys * >>>>>>>>>>> 1) "42e574e7-3b80-424a-b9ff-01072f1e0358" >>>>>>>>>>> >>>>>>>>>>> 127.0.0.1:6379> get "42e574e7-3b80-424a-b9ff-01072f1e0358" >>>>>>>>>>> "\x00>NPY\b\x00\x00\x01\xfc\xf1\xfe\x1b\x00\x00\x00\nj\nip-addressi\x0e165.254.84.238j\x05tokeni$46b87d64-cff3-4b8b-895c-e089ac59544dj\x0bapi-versioni\x02v1j\x0etransaction-idi$42e574e7-3b80-424a-b9ff-01072f1e0358j\adebrief\r\x00\x00\x01YSmeek >>>>>>>>>>> >>>>>>>>>>> Hallie of Withers, Smeg, Harrington and Norvig responded to our >>>>>>>>>>> proposal >>>>>>>>>>> and said his company is rea-\x00\xf1\x06move forward. The >>>>>>>>>>> raty\x00\xf0\x0c$400 per ton of shredded pa\x16\x00\xf1\bwas >>>>>>>>>>> acceptable to >>>>>>>>>>> them,q\x00Bthey0\x00\x80 about 2E\x00\x10sF\x00\xf1Ldocuments every >>>>>>>>>>> month. >>>>>>>>>>> $96,000 in potential revenue annually. I will meet with him >>>>>>>>>>> tomorrow{\x00\"we#\x00@sign\x92\x00\xa0 contract." >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> I don't know what all of those extra characters are. The Java >>>>>>>>>>> app is not picking this item up, so I assume the Java app is not >>>>>>>>>>> seeing >>>>>>>>>>> this as a string. I expected this to look the same as if I had >>>>>>>>>>> written this >>>>>>>>>>> at the terminal: >>>>>>>>>>> >>>>>>>>>>> {'transaction-id' : '42e574e7-3b80-424a-b9ff-01072f1e0358', >>>>>>>>>>> 'debrief' : 'Smeek Hallie of Withers, Smeg, Harrington and Norvig >>>>>>>>>>> responded >>>>>>>>>>> to our proposal and said his company is read to move forward. The >>>>>>>>>>> rate of >>>>>>>>>>> $400 per ton of shredded paper was acceptable to them, and they >>>>>>>>>>> shred about >>>>>>>>>>> 2 tons of documents every month. $96,000 in potential revenue >>>>>>>>>>> annually. I >>>>>>>>>>> will meet with him tomorrow and we will sign the contract.'} >>>>>>>>>>> >>>>>>>>>>> I assume it is easy to get a string into a format that can be >>>>>>>>>>> understood by both a Clojure app and a Java app. I don't care what >>>>>>>>>>> format >>>>>>>>>>> that is, but it needs to be consistent. >>>>>>>>>>> >>>>>>>>>>> Can anyone make suggestions about what I can do to make sure the >>>>>>>>>>> Clojure app and the Java app both write to Redis using a format >>>>>>>>>>> that the >>>>>>>>>>> other will understand? In particular, both apps need to see the >>>>>>>>>>> "'transaction-id". >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> -- >>>>>> You received this message because you are subscribed to the Google >>>>>> Groups "Clojure" group. >>>>>> To post to this group, send email to clo...@googlegroups.com >>>>>> Note that posts from new members are moderated - please be patient >>>>>> with your first post. >>>>>> To unsubscribe from this group, send email to >>>>>> clojure+u...@googlegroups.com >>>>>> For more options, visit this group at >>>>>> http://groups.google.com/group/clojure?hl=en >>>>>> --- >>>>>> You received this message because you are subscribed to a topic in >>>>>> the Google Groups "Clojure" group. >>>>>> To unsubscribe from this topic, visit >>>>>> https://groups.google.com/d/topic/clojure/9swfBxAbT90/unsubscribe. >>>>>> To unsubscribe from this group and all its topics, send an email to >>>>>> clojure+u...@googlegroups.com. >>>>>> For more options, visit https://groups.google.com/d/optout. >>>>>> >>>>> >>>>> >>>>> -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.