Use firestore's FieldPath.documentId() in within nested object

眉间皱痕 提交于 2021-02-19 08:03:05

问题


This is how my data is structured:

firestore db

So an element has a cluster object and the cluster object has a tags object with one or more tag objects.

This is inline with firebase's denormalized data structure Explained here. (We use multi path updates and lookup tables to keep data consistent, this means tags cant be an array!)

I would like to query on the document id's of the nested tags object. I know that firestore.FieldPath.documentId() returns the document id and one can use it in a query like so:

db.collection('elements').where(firestore.FieldPath.documentId(), 'in',  ["a element document id"]).get().then((res) => {
    console.log(res);
}).catch((err) => {
    console.log(err);
});

But I wish to use it on a nested object like so

db.collection('elements').where('cluster.tags.'+firestore.FieldPath.documentId(), 'in',  ["a element document id"]).get().then((res) => {
    console.log(res);
}).catch((err) => {
    console.log(err);
});

I did not expect it to work like my example but I do not see any examples of this. elements.cluster.tags is a valid FieldPath so how would I access the documentId() within a .where() query.

Any ideas?


回答1:


firestore.FieldPath.documentId() doesn't actually return a document ID. It returns FieldPath token object on the client. It can't participate in string concatenation, since it doesn't yet have a final string value on the client. It only materializes an actual string value when interpreted on the server. So, what you're trying to do now isn't really possible. Note that the API documentation for where() shows that it's only meaningful to pass a FieldPath argument can only when it stands alone as the first argument.

If you want to build a path to a field, you need to know its full name. There are no wildcards or substitutions. But that's not even what you need here.

I don't think that the way you have this data structured will meet the needs of your query. It sounds like you need a special field that just contains the IDs of the tags you want to locate inside the document. You can do this by simply adding a new list type field that contains strings of document ID tags that are present. Then you can use an in query to find out if a document ID is present somewhere in that field in any document of the collection.

So, for example:

db
    .collection('elements')
    .where('doc-tags', 'in', ["a element document id"])
    .get()

If doc-tags is a list of tags, this query will find all the documents where any of the requested IDs are present.




回答2:


I hope this works for you. If I understand what you where trying to do you. What I've written will console log your nested tag properties. You are trying to get a document but you only retrieved the collection. By chaining the DOC method, when the promise is resolved you can use the resolved value's(which will be a SnapShot of your tag document) GET method to use a path to your tag's nested properties by using a template strings so you can use an expression to change tagIDs.

db.collection('elements').doc('KKLWwFfdeKgS0viYonXb').get().then(res => {
    console.log(res.get(`cluster.tags.${tagID}`))//or however deep you need to go
}).catch(err => console.log(err))


来源:https://stackoverflow.com/questions/61749371/use-firestores-fieldpath-documentid-in-within-nested-object

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!