2017-03-16 23 views
0

我正在编写一个查询以仅处理数组中的一个项目,但查询正在返回整个数组。发现查询返回数组中的所有项目,尽管只查询一个

我有这样的数据的集合:

"testScenarioId":"100", 
"testSteps":[ 

    { 
    "edit":false, 
    "controlId":1450419683150, 
    "controlName":"scanTextBox", 
    "objProp":"id->articleSearch_scanViewPopup_field", 
    "objPropType":15, 
    "action":{ 
     "id":6 
    }, 
    "screenId":1450419663920, 
    "screenName":"Order.Scan", 
    "applicationId":4, 
    "applicationName":"GSM", 
    "testCaseId":"100", 
    "index":1, 
    "testStepNumber":"1" 
    }, 
    { 
    "edit":false, 
    "controlId":1450419683894, 
    "controlName":"scansearchbutton", 
    "objProp":"id->articleSearch_scanViewPopup_field_HelpIcon", 
    "objPropType":17, 
    "action":{ 
     "id":2 
    }, 
    "screenId":1450419663920, 
    "screenName":"Order.Scan", 
    "applicationId":4, 
    "applicationName":"GSM", 
    "testCaseId":"100", 
    "index":2, 
    "testStepNumber":"2" 
    }]} 

我想基于标准"testScenarioId" : "100""testSteps.testStepNumber" : "1"更新集合;这意味着,当我运行此命令的testSteps数组中的第一个文件必须更新,如下图所示

{

"edit":false, 
"controlId":1450419683150, 
"controlName":"scanTextBox", 
"objProp":"id->articleSearch_scanViewPopup_field", 
"objPropType":15, 
"action":{ 
    "id":6 
}, 
"screenId":1450419663920, 
"screenName":"Order.Scan", 
"applicationId":4, 
"applicationName":"GSM", 
"testCaseId":"100", 
"index":1, 
"testStepNumber":"1" 

}

但让我吃惊:

db.TestSteps.find({"testScenarioId":"100","testSteps.testStepNumber":"1"}) 

在mongo shell中,我得到了全部是这个文件在testSteps数组中。

编辑:我想知道的Java代码,以更新使用上述条件的阵列中的一文件。

在此先感谢。

+2

喜非难和欢迎堆栈溢出。请记住,find查询中的条件仅确定集合中的哪些文档被返回;它们不会影响返回中包含哪些子文档(在数组中)。 要从数组中返回一个项目,您需要查看聚合查询中的[unwind operator](https://docs.mongodb.com/manual/reference/operator/aggregation/unwind/)。 –

回答

0

查询的文档

您可以在findprojection参数使用$ projection operator

find命令的语法是:

find(query, projection) 

所以这应该工作:

db.TestSteps.find({"testScenarioId":"100","testSteps.testStepNumber":"1"}, { 'testSteps.$': 1 }) 
  • 注意,当您指定的projection,只有选定的领域会出现,所以如果你需要返回其他字段,将它们添加到你的投影。 了解更多关于投影here

更新文件

要基于搜索的数组元素的更新,你也可以你的$:

​​

中$既定的目标$ operator只是在查询中匹配的第一个数组元素

使用find,修改它获取的元素,并将其保存回

您需要:

  1. 从文档获取文档与数组元素
  2. 只提取元素
  3. 将元素修改为你想要的
  4. 将它保存回原位置 - 覆盖原始元素


var doc = db.TestSteps.findOne({"testScenarioId":"100","testSteps.testStepNumber":"1"}, { 'testSteps.$': 1 }); 
var the_element = doc.testSteps[0]; 
var updated_element = changeThisElement(the_element); 
db.TestSteps.update(
    {"testScenarioId":"100","testSteps.testStepNumber":"1"}, 
    {$set: { 'testSteps.$': updated_element }} 
) 
+0

嗨Marmor, 感谢您的回复。 mongo shell命令正在工作,我得到一个匹配的文档。现在我想通过java来更新它,使用从UI获得的对象。更确切地说,如果我在UI中更新记录,完整记录作为对象将被传递给java函数作为参数进行更新,以获取mongodb中更新的记录。 对不起,如果我不清楚我的问题。 – razz

+0

好吧,我在js中添加了适合你的代码,但需要转换为Java。没有测试过,希望这对你有用... – marmor

+0

谢谢你这么多,你让我的生活变得轻松:)。 我能写出逻辑 – razz

0

尝试增加在查找查询$elemMatch

db.TestSteps.find({"testScenarioId":"100", "testSteps": $elemMatch: {"testStepNumber":"1"}}) 
+0

Hi Vishwa, 谢谢您的查询。提供的查询引发语法错误。我在下面修改后启动它, db.TestSteps.find({“testScenarioId”:“100”,“testSteps”:{$ elemMatch:{“testStepNumber”:“1”}}})我还在testSteps数组中的所有文档 – razz

0

你需要添加投影。

db.TestSteps.find({ "testScenarioId":"100"},{"testSteps": { $elemMatch: {"testStepNumber":"1" } } })