如何查询通配符后的多个值?



我有一个json对象,像这样:

{ 
_id: "12345",
identifier: [
{ 
value: "1",
system: "system1",
text: "text!"
},
{ 
value: "2",
system: "system1"
}
]
}

我如何使用XDevAPI SearchConditionStr在标识符数组中寻找值+系统的特定组合?像这样,但这似乎不工作…

collection.find("'${identifier.value}' IN identifier[*].value && '${identifier.system} IN identifier[*].system")

通过使用IN运算符,下面发生的事情基本上是对JSON_CONTAINS()的调用。

所以,如果你调用:

collection.find(":v IN identifier[*].value && :s IN identifier[*].system")
.bind('v', '1')
.bind('s', 'system1')
.execute()

最后执行的是(简化):

JSON_CONTAINS('["1", "2"]', '"2"') AND JSON_CONTAINS('["system1", "system1"]', '"system1"')

在本例中,这两个条件都为真,并且将返回文档。

原子单元是文档(而不是该文档的切片)。因此,在您的情况下,无论value和/或system的值如何,您仍然在寻找相同的文档(其_id'12345'的文档)。使用这样的语句,如果所有搜索值都是文档的一部分,则返回文档,如果不包含搜索值,则不返回文档。

例如,下面的语句不会产生任何结果:

collection.find(":v IN identifier[*].value && :s IN identifier[*].system")
.bind('v', '1')
.bind('s', 'system2')
.execute()

编辑:潜在的解决方案

我不认为使用CRUD API将允许执行这种"挑选",但您总是可以使用SQL。在这种情况下,想到的一种策略是使用JSON_SEARCH()来检索与identifier[*].valueidentifier[*].system范围内的每个值对应的路径数组,即数组索引,并使用JSON_OVERLAPS()来确保它们是相等的。

session.sql(`select * from collection WHERE json_overlaps(json_search(json_extract(doc, '$.identifier[*].value'), 'all', ?), json_search(json_extract(doc, '$.identifier[*].system'), 'all', ?))`)
.bind('2', 'system1')
.execute()

在这种情况下,结果集将只包括identifier数组包含至少一个JSON对象元素的文档,其中value等于'2',system等于system1。过滤器有效地应用于单个数组项,而不是聚合,就像基本的IN操作一样。

免责声明:我是MySQL X DevAPI Connector for Node.js的首席开发者

最新更新