def add(item, opts = {})
      opts = { :skip_duplicate_check => false }.merge(opts)
      raise ArgumentError, "Items must specify both an id and a term" unless item["id"] && item["term"]
      
      # kill any old items with this id
      remove("id" => item["id"]) unless opts[:skip_duplicate_check]
      
      Soulmate.redis.pipelined do
        # store the raw data in a separate key to reduce memory usage
        Soulmate.redis.hset(database, item["id"], MultiJson.encode(item))
        phrase = ([item["term"]] + (item["aliases"] || [])).join(' ')
        prefixes_for_phrase(phrase).each do |p|
          Soulmate.redis.sadd(base, p) # remember this prefix in a master set
          Soulmate.redis.zadd("#{base}:#{p}", item["score"], item["id"]) # store the id of this term in the index
        end
      end
    end
def add(item, opts = {})
      opts = { :skip_duplicate_check => false }.merge(opts)
      raise ArgumentError, "Items must specify both an id and a term" unless item["id"] && item["term"]
      
      # kill any old items with this id
      remove("id" => item["id"]) unless opts[:skip_duplicate_check]
      
      Soulmate.redis.pipelined do
        # store the raw data in a separate key to reduce memory usage
        Soulmate.redis.hset(database, item["id"], MultiJson.encode(item))
        phrase = ([item["term"]] + (item["aliases"] || [])).join(' ')
        prefixes_for_phrase(phrase).each do |p|
          Soulmate.redis.sadd(base, p) # remember this prefix in a master set
          Soulmate.redis.zadd("#{base}:#{p}", item["score"], item["id"]) # store the id of this term in the index
        end
      end
    end
"id", "term", "score", "aliases", "data"