BIMserver icon indicating copy to clipboard operation
BIMserver copied to clipboard

Query language behaves oddly with streaming serializer

Open GiacomoManzoli opened this issue 6 years ago • 6 comments

I'm trying to run the following query to fetch several data (type, properties and quantities) of an IfcObject given its GUID.

{
  "doublebuffer": true,
  "guid": "<elementGUID>",
  "includes": [
    {
      "type": {
        "name": "IfcObject",
        "includeAllSubTypes": true
      },
      "fields": [
        "IsDefinedBy"
      ],
      "includes": [
        {
          "type": "IfcRelDefinesByProperties",
          "fields": [
            "RelatingPropertyDefinition"
          ],
          "includes": [
            {
              "type": "IfcElementQuantity",
              "fields": [
                "Quantities"
              ],
              "includes": [
                {
                  "type": "IfcPhysicalComplexQuantity",
                  "fields": [
                    "HasQuantities"
                  ]
                }
              ]
            },
            {
              "type": "IfcPropertySet",
              "fields": [
                "HasProperties"
              ],
              "includes": [
                {
                  "type": "IfcComplexProperty",
                  "fields": [
                    "HasProperties"
                  ]
                }
              ]
            }
          ]
        },
        {
          "type": "IfcRelDefinesByType",
          "fields": [
            "RelatingType"
          ],
          "includes": [
            {
              "type": {
                "name": "IfcTypeObject",
                "includeAllSubTypes": true
              }
            }
          ]
        }
      ]
    }
  ]
}

with the following code

this.model.bimServerApi.getJsonStreamingSerializer((serializer: any) => {
    this.model.bimServerApi.call(
        "ServiceInterface",
        "download",
        {
            roids: [this.model.roid],
            query: JSON.stringify(query),
            serializerOid: serializer.oid,
            sync: false
        },
        (topicId: number) => {
            let handled = false
            this.model.bimServerApi.registerProgressHandler(topicId, (topicId: number, state: any) => {
                if (state.title == "Done preparing" && !handled) {
                    handled = true
                    const url = this.model.bimServerApi.generateRevisionDownloadUrl({
                        topicId: topicId,
                        serializerOid: serializer.oid
                    })
                    this.model.bimServerApi.getJson(url, null, (data: QResultRaw) => {
                        // console.log("-------")
                        // console.log("query", data)
                        // console.log("-------")

                        this.model.bimServerApi.call(
                            "ServiceInterface",
                            "cleanupLongAction",
                            {
                                topicId: topicId
                            },
                            () => {}
                        )
                        resolve(data)
                    })
                } else if (state.state == "AS_ERROR") {
                    console.error(state.title)
                    reject(state)
                }
            })
        }
    )
})

I've noticed that, if the GUID exists in the model, the query gives the same/similar result with both the JsonSerializer and the JsonStreamingSerializer.

But, if the GUID doesn't exist, the streaming serializer behaves differently than the non-streaming one.

More in depth:

  • the streaming serializer with doublebuffer set to true gives to many result (it loads everything)
  • the streaming serializer with doublebuffer set to false gives no result (and that's ok)
  • the non-streaming always raises the exception java.lang.RuntimeException: Object not found

I've read this comment https://github.com/opensourceBIM/BIMserver/issues/1081#issuecomment-576399075 but, from what i've understood, the doublebuffer flag should be true (and in this case the flag set to true gives the wrong result).

I think that there is something odd, but i don't know if this is a bug of one of the serializers or this is the intended behavior. In the latter case, i think that a more in-depth description of the serializers and their relation with the query language it's really helpful.

GiacomoManzoli avatar Jan 28 '20 23:01 GiacomoManzoli

With the same query, i've also noticed that the JsonSerializer gives only the query results, something like:

{
    "objects": [
      ...
    ]
}

while the JsonStreamingSerialier gives also the header data:

{
    "header": {
        "_i": 65636,
        "_u": "79fa359c-7ef1-4b32-aaf4-9cab7386bfe6",
        "_r": 1,
        "_t": "IfcHeader",
        "_s": 1,
        "filename": "...",
        "timeStamp": 1571320724000,
        "author": [
            "Architect"
        ],
        "organization": [
            "Building Designer Office"
        ],
        "preProcessorVersion": "The EXPRESS Data Manager Version 5.02.0100.09 : 18 Aug 2016",
        "originatingSystem": "IFC file generated by GRAPHISOFT ARCHICAD 23.0.0 ITA FULL Macintosh version (IFC add-on version: 3003 ITA FULL).",
        "ifcSchemaVersion": "IFC2X3",
        "authorization": "The authorising person"
    },
    "objects": [
        ...
    ]
}

why there is this difference?

GiacomoManzoli avatar Jan 29 '20 09:01 GiacomoManzoli

The JsonSerializer has not been updated a lot, in fact it should be deprecated, I just did that. The results of the streaming serializers should be the same with doublebuffer=true, if they are not (such as when the GUID was not found), those are bugs that need to be fixed. I'll leave this issue open to fix this specific bug.

rubendel avatar Jan 30 '20 09:01 rubendel

This is fixed now in git head, will be in the next release.

rubendel avatar Jan 30 '20 10:01 rubendel

Thank you!

So, with the next release, the query for a missing GUID with doublebuffer=true serialized withJsonStreamingSerializer shouldn't give any result, right?

GiacomoManzoli avatar Jan 30 '20 12:01 GiacomoManzoli

Correct, no entities, only the IFC header, which we might have to make a query parameter as well, something like

"includeHeader": false

rubendel avatar Jan 30 '20 12:01 rubendel

The original issue seems to be resolved, but I'll keep this open as a feature request. However, I am not convinced of the includeHeader option, because SPF files for example may not be valid without header information.

hlg avatar Apr 12 '21 11:04 hlg