搜索和查询知识图谱服务

有两种方法可从知识图谱中检索记录。搜索允许您对知识图谱运行自由文本搜索。查询提供了一种更细致的方式,以 openCypher 查询的形式检索对知识图谱执行的记录。搜索和查询都有两种模式:非流式和流式。流式搜索流式查询以小的 chunk 块返回结果,允许客户端立即开始处理返回的数据,而不是等待返回整个结果集后再进行处理。流式处理更快、更高效,并且将检索所有匹配的记录,即使总数超过服务定义中设置的搜索和查询限制也是如此。流的另一个好处是请求是编码的,这意味着它比传统的 HTTP GET 或 JSON POST 的 body 小得多。当试图对非常大的参数进行查询时 (例如,大型 ID 集或与复杂几何体相交),这一点尤其重要。

使用 GraphSearchStreaming 可通过 executeSearchStreaming() 方法搜索图谱中实体关系的属性。其他可选搜索参数(如指定要在其中进行搜索的实体或关系类型列表)可以进一步限制搜索。搜索知识图谱的最有效方法是使用流式搜索

展开
代码块使用深色复制
                                                                                                                                                                                                                          
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
        // define the search terms
        const search = new StreamingSearch({
          searchQuery: "solar",
          typeCategoryFilter: "both",
          // optional parameters
          returnSearchContext: false,
          start: 1, //start at the first record
          num: 200, //return 200 records.
          namedTypesFilter: ["Company", "Supplier", "Part"],
          globalIdsFilter: ["aiw-924", "esj-856", "snh-571", "hnk-9751", "pyo-7884", "hjl-2541"]
        });

        // search the knowledge graph
        KnowledgeGraphModule.executeSearchStreaming(
          // knowledge graph resources
          knowledgeGraph,
          // search parameters
          search
        ).then((streamingSearchResult) => {
          // the result of a streaming search is a readableStream which must be read to access the data.
          readStream(streamingSearchResult);
        });
展开

查询

使用 executeQueryStreaming() 方法可检索实体和关系的具体子集及其属性。查询图谱使用 openCypher 查询的 GeoScene 实现,该查询支持只读操作。在从图谱返回的结果和返回的数据结构方面,查询提供了更大的灵活性。例如,假设有一个供应链图谱,该图谱包含制造 Plant 的实体,其制造的 PartSupplier 进行购买;工厂和它生产的零件之间有一种 produces 关系,供应商和它购买零件的工厂之间有一种 buys_part 关系。

要查找 Supplier 类型的前十个实体,可以使用查询 MATCH (m:Supplier) RETURN m LIMIT 10。要发现哪些零件 (p) 是由哪些工厂 (pl) 生产的,可以使用查询通过 produces 关系来匹配实体,例如 MATCH (pl:Plant)-[ :produces]->(p) RETURN pl,pGraphQueryStreaming 还提供了将参数绑定到查询 (如边界框) 的功能。有关其他查询参数,请参阅 GraphQueryStreaming

展开
代码块使用深色复制
                                                                                                                                                                                                                          
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
        // select all Supplier's that are in the Washington DC area and the parts that they buy
        const query = `MATCH (s:Supplier)-[:buys_part]-(p:Part)
               geoscene.graph.ST_Intersects($geom, s.geometry)
               RETURN s,p`;

        KnowledgeGraphModule.executeQueryStreaming(knowledgeGraph, {
          openCypherQuery: query,
          bindParameters: {
            //bounding box around Washington DC
            geom: new Polygon({
              rings: [
                [
                  [38, -78],
                  [39, -78],
                  [39, -76],
                  [-38, -76],
                  [-38, -78]
                ]
              ]
            })
          }
        }).then((streamingQueryResult) => {
          // the result of a streaming query is a readableStream which must be read to access the data.
          readStream(streamingQueryResult);
        });
展开

使用流结果

流式搜索或流式查询的结果是 GraphQueryStreamingResult,其中包含一个可读流,必须使用 getReader() 函数读取该流才能访问数据。可读流将返回记录块,直到返回所有记录。每个块都可立即处理,例如将数据添加到表或将具有几何的实体添加到地图。

展开
代码块使用深色复制
                                                                                                                                                                                                                          
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
        // a function to read the stream returned from the search
        const readStream = async (streamingQueryResult) => {
          let time = Date.now();
          let reader = streamingQueryResult.resultRowsStream.getReader();
          try {
            while (true) {
              const { done, value } = await reader.read();
              if (done) {
                console.log(`Stream completed and closed: ${(Date.now() - time) / 1000} seconds`, value);
                break;
              }
              // begin working with the data from the returned chunk immediately.
              // list the parts bought by each supplier
              let supplierParts = [];

              // each element of the result array will contain one supplier and one part it buys
              for (let v in value){
                let supplier = value[v][0].properties.Name
                let part = value [v][1].properties.Name
                if(!(supplier in supplierParts)){
                  supplierParts[supplier] = [];
                }

                // collect parts by supplier that buys them
                supplierParts[supplier].push(part);
              }
              // make a table that lists the suppliers and the parts they buy
              let table = document.getElementById('supplierTableBody');
              for (let supplier in supplierParts){
                table.appendChild(`<tr><td>${supplier}</td><td>${supplierParts.supplier.join(', ')}</td>`);
              }
              //  Entities that have geometry can be drawn on the map
              addToMap(value);
              // Since
            }
            // if there is an error in returning the stream or the stream is aborted
          } catch (err) {
            if (err.name === "AbortError") {
              console.log("Request aborted as expected");
            } else {
              throw err;
            }
          }
        };

        // function to add entities with geometry to a map
        function addToMap(records) {
          let features = [];
          //extract the geometry from the returned results and add it to a feature layer
          for (let i = 0; i < records.length; i++) {
            let item = records[i][0];
            let props = item.properties;
            // if the returned item contains geometry,
            //extract the geometry information to create features
            if ("shape" in props) {
              features.push({
                geometry: {
                  type: props.shape.type,
                  x: props.shape.longitude,
                  y: props.shape.latitude
                },
                attributes: props
              });
            }
          }

          // create feature layer
          let featureLayer = new FeatureLayer({
            source: features,
            renderer: {
              type: "unique-value", // autocasts as new UniqueValueRenderer()
              defaultSymbol: {
                type: "simple-marker", // autocasts as new SimpleMarkerSymbol()
                size: 2,
                color: "#009816",
                outline: null
              }
            }
          });
          map.add(featureLayer);
        }
展开

您的浏览器不再受支持。请升级您的浏览器以获得最佳体验。