Querying for a dictionary inside a document

I am putting the following in the local DB of our Android app:

fun registerExperiment(experiment: Experiment) {
    DBManager("experiments", config).create {
        val doc = MutableDocument()
        doc.setString("name", experiment.name)
        doc.setDate("start_date", experiment.duration.startDate)
        doc.setDate("end_date", experiment.duration.endDate)
        doc.setString("status", experiment.status.toString())
        val sensorsDictionary = MutableDictionary()
        experiment.sensorsInfo.forEachIndexed { index, _ ->
            sensorsDictionary.setString(experiment.sensorsInfo[index].label, experiment.sensorsInfo[index].value)
        }

        doc.setDictionary("internal_environment", sensorsDictionary)
    }
}

From this method, you see, I’m putting in an experiment entry: metadata consisting of names, start and end dates, and a status (queued, finished, etc). The create() function is a higher-order function that takes in whatever that results in a mutable document, so don’t think too much about when execute() is performed, it’s done somewhere else. Anyway, you can also see a dictionary containing the actual sensor information (humidity, co2, water level, pH, etc), however, I just can’t flatten it along with the metadata because the user is allowed to not have an entry for a certain sensor, that’s why I stored it as a Couchbase Dictionary. The SensorInfo model class simply looks like this:

@Parcelize
data class SensorInfo (val label: String, var value: String) : Parcelable

How do I query for this dictionary I stored and how do I extract its data? Here’s how I read the data so far:

fun getExperiments(): MutableList<Experiment> {
    val resultSet: ResultSet? = DBManager("experiments", config).read { currentDatabase ->
        QueryBuilder.select(SelectResult.property("name"),
                            SelectResult.property("start_date"),
                            SelectResult.property("end_date"),
                            SelectResult.property("status"),
                            SelectResult.property("internal_environment"))
                    .from(DataSource.database(currentDatabase))
    }

    val experiments = mutableListOf<Experiment>()
    resultSet?.let {
        it.forEach { result ->
            val experiment = Experiment(result.getString("name"),
                    enumValueOf(result.getString("status")),
                    Duration(result.getDate("start_date"), result.getDate("end_date")))

            /* TODO: fill in the sensor info list with data from dictionary */
            
            experiments.add(experiment)
        }
    }

    return experiments
}

Thank you.

P.S.
If you need to see how create() and read() are implemented, here it is: (feel free to criticize it if you want, but so far, this pattern has served me well with my CRUD operations):

    override fun create(customCreate: () -> MutableDocument) {
    openDB()
    val doc = customCreate()

    try {
        currentDatabase.save(doc)
        currentDatabase.close()
    } catch (e: CouchbaseLiteException) {
        e.printStackTrace()
    }
}

    override fun read(customQuery: (database: Database) -> Query): ResultSet {
    openDB()
    val query = customQuery(currentDatabase)
    lateinit var resultSet: ResultSet

    try {
        resultSet = query.execute()
        //currentDatabase.close()
    } catch (e: CouchbaseLiteException){
        e.printStackTrace()
    }

    return resultSet
}

Not sure I fully understand the issue here.

What is the output of your query result ? Did you try getDictionary on the “internal_environment” key ? What do you see?

I think it would be simpler if you provided a sample document and what you expect the resultset of query to be

Oh thank you for the reply. I figured it out, I just had to make a map variable and cast the couchbase dictionary to map using toMap()