# Qserv - not finding objects via director\_key

**URL:** <https://www.rubin.community/t/qserv-not-finding-objects-via-director-key/6050>\
**Category:** Support\
**Tags:** qserv\
**Created:** [November 4, 2021, 1:45pm UTC](https://www.rubin.community/t/qserv-not-finding-objects-via-director-key/6050 "2021-11-04T13:45:25Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![MRead](https://sea2.discourse-cdn.com/flex002/user_avatar/www.rubin.community/mread/32/2519_2.png) [@MRead](https://www.rubin.community/u/MRead)\
**Post date:** [November 4, 2021, 1:45pm UTC](https://www.rubin.community/t/qserv-not-finding-objects-via-director-key/6050/1 "2021-11-04T13:45:26Z")

</div>

Hi

So I’ve manged to load some data into our (two worker node) qserv instance. Everything seemed to go in OK.

select count(\*) from Xmatch;

gives the correct answer.

However lookups using the directorID do not find any results.

eg select objectId from Xmatch limit 1; =\> 213625183610364160

select \* from Xmatch where objectId=213625183610364160; =\> Empty set

select \* from Xmatch where objectId \>=0; =\> Empty set

Other lookups work (select \* from Xmatch where wise\_cntr=836149901351037045;), so it looks like I’ve messed up the directorId set-up somehow or missed a step or two.

I believe I’ve partitioned and created the DB with the same family. However I’m not sure about the use of the part.id entry during partitioning. It makes no difference to the chunk files themselves? It creates a chunk\_object\_index.txt but this is not used?

During database creation “auto\_build\_secondary\_index”:1

Later, the commit transaction returned “secondary-index-build-success”:0,“success”:1

Is secondary-index-build-success":0 the issue?

I attach a record my workflow for a single chunk of data database publication.

[qserva.txt](https://www.rubin.community/uploads/short-url/HRcqznzZvFoOv97DTuYW301oJg.txt) (5.2 KB)

Originally the director\_key was set to “gaia\_source\_ID” but I tried changing it to objectId in case the underscores affected things. The director\_key is not the first column in the tsv files, does it need to be?

Thanks  
Mike

---

<div class="post-metadata">

**Author:** ![gapon](https://sea2.discourse-cdn.com/flex002/user_avatar/www.rubin.community/gapon/32/264_2.png) [@gapon](https://www.rubin.community/u/gapon)\
**Post date:** [November 4, 2021, 6:46pm UTC](https://www.rubin.community/t/qserv-not-finding-objects-via-director-key/6050/2 "2021-11-04T18:46:35Z")

</div>

Hi Mike

let me address your question on the `director` (used to be known as the “secondary”) index creation failure first. I will answer the second question (on `sph-partition`) in a separate reply.

I’ve analyzed the report you’ve attached to your message, and everything but that `“secondary-index-build-success”:0` reported by the transaction commit looks right to me. The transaction commit procedure was designed to report `"success":1` even if the director index creation fails. There are two reasons for that. Firstly, this index is an optional optimization for Qserv. Qserv may still function w/o using the one by resorting to the full table scan if no index is found, or if the index is found empty (we may still have a bug in Qserv as it doesn’t seem to do what I have just said). The second reason is that you can always (re-)build this index after publishing a catalog. Instructions can be found at [Ingest: 9.4. Building the "secondary index" - Data Management - Confluence](https://confluence.lsstcorp.org/pages/viewpage.action?pageId=139035579). Specifically for your Qserv setup you would need to run the following operation:

```auto
curl "http://localhost:8080/ingest/index/secondary" \
  -X POST -H "Content-Type: application/json" \
  -d'{"database":"testWP311a","allow_for_published":1,"rebuild":1,"local":1,"auth_key":""}' 

```

Now to possible reasons of the failure. I think the problem was caused by not using this option when registering the database:

```auto
"local_load_secondary_index":1

```

You would need to add it here:

```auto
curl "http://localhost:8080/ingest/database" \
   -X POST -H "Content-Type: application/json" \
 -d '{"database":"testWP311a","auto_build_secondary_index":1, "local_load_secondary_index":1, "num_stripes":340,"num_sub_stripes":3,"overlap":0.01667,"auth_key":""}'

```

Further details on this could be found at [Ingest: 11.1.2.1. Register a database - Data Management - Confluence](https://confluence.lsstcorp.org/display/DM/Ingest%3A+11.1.2.1.+Register+a+database).

So, now you have two options:

- keep your database and rebuild the index as I explained above, or
- delete the database and do the ingest from scratch with the corrected configuration of the database

Databases can be deleted as explained at [Ingest: 11.1.2.3. Delete a database or a table - Data Management - Confluence](https://confluence.lsstcorp.org/display/DM/Ingest%3A+11.1.2.3.+Delete+a+database+or+a+table)

I hope this will help! I should also mention that if it would work better for you then you may always post questions and comments at the LSSTC Slack channel [#dm-qserv](https://lsstc.slack.com/archives/C2B70NXFD).

And I owe you an answer to your second question.

Regards,  
Igor

---

<div class="post-metadata">

**Author:** ![gapon](https://sea2.discourse-cdn.com/flex002/user_avatar/www.rubin.community/gapon/32/264_2.png) [@gapon](https://www.rubin.community/u/gapon)\
**Post date:** [November 4, 2021, 8:52pm UTC](https://www.rubin.community/t/qserv-not-finding-objects-via-director-key/6050/3 "2021-11-04T20:52:43Z")

</div>

Hi Mike

regarding your questions on partitioning the input data for Qserv. Your first question in this context was:

> Originally the director\_key was set to “gaia\_source\_ID” but I tried changing it to objectId in case the underscores affected things. The director\_key is not the first column in the tsv files, does it need to be?

Underscore wouldn’t be a problem for as long as it doesn’t start with `qserv_` or the names of the columns are not `chunkId` or `subChunkId`. Qserv may inject special columns that start with the prefix `qserv_` to store various meta information within the data tables. At the moment we have only one such column `qserv_trans_id`. More columns could be added in the future. The other two columns I’ve mentioned above also have special meanings in Qserv.

Now, let me move to another topic on the meaning of the parameter `part.id` in a config file for the `sph-partition` tool. Please, note that you may also specify this parameter as the command-line option when running the tool:

```auto
sph-partition --part.id=<col-name> ...

```

This is the name of a field that has an object identifier. If it’s provided then the secondary index will be open or created.

To explain why or when one might need to use this option, let me dive a bit into a design of Qserv. As you already know, Qserv implements the **horizontal** (which is different from MySQL’s **vertical** ) partitioning of tables by spreading table data between worker nodes. Each node has a subset of the full table’s data. The data are stored in the “chunked” tables. Those tables are named after the name of the main (logical) table such as your `Xmatch` and the corresponding value of the `chunkId` column. For example, `qserv-worker-0` of your set up would have the following tables after you finish the ingest of chunk `179619`:

```auto
testWP311a.Xmatch_179619
testWP311a.XmatchFullOverlap_179619
...

```

Tables that are partitioned in this way are known as **partitioned** tables. Note that Qserv also supports fully replicated tables that are known as **regular** tables. A full copy of a given regular table is supposed to be ingested into each worker node of Qserv. I’m not going to discuss further details on why one would want to ingest a table as the **regular** one. It would be another interesting topic that you may eventually hit on the road. Back to the **partitioned** tables. Tables of this kind form a logical tree, in which there is at least one so-called **director** table, and 0 or more so-called **dependent** ones. Qserv knows (from configuration files that you’re presenting to the Ingest system) what flavor of the table you have in each case, and uses this information in processing queries that involve either (or both of these tables).

In any case, data of both tables have to be partitioned in order to be ingested into Qserv. The ingest-time attribute **is\_director** in the table’s config file is meant to differentiate between these tables.

- Note that in the current version 7 of the Replication/Ingest system there is a slightly different mechanism that describes this property. For further details, see [https://confluence.lsstcorp.org/display/DM/Ingest%3A+9.6.+Ingesting+catalogs+with+many+director+tables](https://confluence.lsstcorp.org/display/DM/Ingest%3A+9.6.+Ingesting+catalogs+with+many+director+tables). You may ignore this for now since you seem to have the pre-version-7 of Qserv deployed.

What is important to know here is that rows of the dependent tables are required to be associated with the corresponding rows in some director table. This association is similar to the `FK -> PK` association in the traditional RDBMS. Qserv requires that rows that are linked by this association in _both_ director and the dependent tables be found within the same chunk. This introduction brings us to the essence of your question - when partitioning the input data of the director and the dependent tables we need to ensure that the corresponding rows were placed within the correct chunks, so that Qserv could successfully execure queries like this:

```auto
SELECT * FROM director AS dir, depedent AS dep WHERE dir.prop == "123" AND dir.objecId = dep.objectId;

```

The director tables are always partitioned on the values of their RA/DEC columns. Things are a bit more complicated for the dependent tables. There are two options here:

1. If the dependent table has the RA/DEC columns, and values of these columns for a given row exactly match the values of the RA/DEC columns of the corresponding row of the director table then you may partition the dependent table based on RA/DEC. In this case, you don’t need to specify the option `--part.id`. Note that you’re still required to ensure your data are correct in terms of the referential integrity across rows of the related tables so that for each row’s `objectId` in the dependent table there is a matching row with the same `objectid` in the dependent tables (of that director).
2. The second scenario is seen when a dependent table doesn’t have spatial columns. In this case, you would have to help the partitioning tool `sph-partition` to figure out at which chunk to place each row of the dependent table. This requires following object identifiers from the dependent tables to their director table during the partitioning stage. The option `--part.id` is used by the tool to create a simple file-based index at `chunk_object_index.txt`. Each line of this index has triples of 3 columns: (`objectId`,`chunkId`,`subChunkId`). Note that this index is partial as it’s based on what’s found in your input files. If you have many input files (`CSV`/`TSV`) then you would have to consolidate all files you get after finishing partitioning data of the director table into a single file. You will need this file when partitioning the input data of the corresponding dependent tables. You would have to pass a location of that index file to the tool via the option `--part.id-url=<path>`. Note that you would also need to specify the name of the `objectid` column of the depedent table as well via `--part.id=<col-name>`. This combination of parameters will tell the tool that you’re partitioning the dependent table so that it could pull chunk numbers for each row of the dependent table from the index file.

I hope this helps. Though, this is a complicated topic. Please, contact me should you have any further questions on this subject. I may also need to extend the documentation on the Ingest system to cover this topic and to provide examples on how to partition data of the related (director and dependent) tables.

Regards,  
Igor

---

<div class="post-metadata">

**Author:** ![MRead](https://sea2.discourse-cdn.com/flex002/user_avatar/www.rubin.community/mread/32/2519_2.png) [@MRead](https://www.rubin.community/u/MRead)\
**Post date:** [November 5, 2021, 4:57pm UTC](https://www.rubin.community/t/qserv-not-finding-objects-via-director-key/6050/4 "2021-11-05T16:57:44Z")

</div>

Dear Igor

Many thanks!

Both methods worked (re-creating the database with  
`"local_load_secondary_index":1`  
and re-generating the index (on a larger similarly affected DB).

I wasn’t a member of the slack LSSTC but I am now, so I’ll follow up there as I have some more questions I’m afraid though I’ll have more of a play first.

Thanks again  
Mike
