Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/305.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/mongodb/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Morphia:在嵌入对象列表中搜索空值_Java_Mongodb_Morphia - Fatal编程技术网

Java Morphia:在嵌入对象列表中搜索空值

Java Morphia:在嵌入对象列表中搜索空值,java,mongodb,morphia,Java,Mongodb,Morphia,我有一个嵌入式实体列表: @Embedded private List<EmbeddedEntity> embedded = new ArrayList<EmbeddedEntity>(); 如果列表为空,或者只有一个条目,其中foo有一个值,而bar还不存在,则此选项可以正常工作。但是,只要任何bar属性有一个值,查询就会返回错误的结果。因此,我正在寻找一个查询,它遍历所有嵌入的实体,并在任何缺少的条上激发。可能吗 示例数据: // the query does no

我有一个嵌入式实体列表:

@Embedded
private List<EmbeddedEntity> embedded = new ArrayList<EmbeddedEntity>();
如果列表为空,或者只有一个条目,其中foo有一个值,而bar还不存在,则此选项可以正常工作。但是,只要任何bar属性有一个值,查询就会返回错误的结果。因此,我正在寻找一个查询,它遍历所有嵌入的实体,并在任何缺少的条上激发。可能吗

示例数据:

// the query does not pick up the entity as it doesn't have a foo -
// that's what I want
{ uuid: "...", [ { embedded: } ] }

// the query picks up the entity as there is a foo but no bar -
// that's what I want
{ uuid: "...", [ { embedded: { foo: date } } ] }

// the query does not pick up the entity - that's not what I want
// as one foo has a value and its bar doesn't
{ uuid: "...", [ { embedded: { foo: date, bar: date } },
                 { embedded: { foo: date } }
               ] }
PS:我用.fieldembedded.bar.hasThisOneFull得到了相同的结果

PPS:手动迭代列表元素实际上不是一个选项,因为我想使用查询进行更新操作


PPS:我认为这是Morphia中的一个bug-请参阅下面我的答案以了解解决方法

我找到了一个解决方法。虽然我似乎无法查询null,但我可以查询特定的值

在我的例子中,bar字段是一个日期。因此,我可以用private Date bar=new Date0初始化实体-在我的例子中,这显然是一个无效的日期,从未使用过。因此,查询如下所示:

Query<Entity> query = mongoDataStore
    .find(Entity.class)
    .field("uuid").equal(uuid)
    .field("embedded.foo").exists()
    .field("embedded.bar").hasThisOne(new Date(0));

我找到了一个解决办法。虽然我似乎无法查询null,但我可以查询特定的值

在我的例子中,bar字段是一个日期。因此,我可以用private Date bar=new Date0初始化实体-在我的例子中,这显然是一个无效的日期,从未使用过。因此,查询如下所示:

Query<Entity> query = mongoDataStore
    .find(Entity.class)
    .field("uuid").equal(uuid)
    .field("embedded.foo").exists()
    .field("embedded.bar").hasThisOne(new Date(0));

我认为您的模式在概念上有问题。请记住,您总是查询顶级文档。查询不起作用的原因是,您要求它返回顶级文档,其中至少一个元素具有foo,而至少一个元素没有bar值。请注意,这两个条件不必应用于同一数组元素

您可以使用$elemMatch在MongoDB中执行您想要的操作:

查找{embedded:{$elemMatch:{foo:{$exists:true},bar:{$exists:false}}},如下所示:

> db.test.save({embedded:[]})
> db.test.save({embedded:[{foo:1}]})
> db.test.save({embedded:[{bar:1}]})
> db.test.save({embedded:[{foo:1, bar:1}]})
> db.test.find({embedded:{$elemMatch:{foo:{$exists:true}, bar:{$exists:false}}}})
{ "_id" : ObjectId("4f60c4d56fa40267a11d2f2c"), "embedded" : [ { "foo" : 1 } ] }
如果null是bar的有效值,您只需将其更改为:

> db.test.save({embedded:[{foo:1, bar:null}]})
> db.test.find({embedded:{$elemMatch:{foo:{$exists:true}, $or:[{bar:{$exists:false}}, {bar:null}]}}})
{ "_id" : ObjectId("4f60c4d56fa40267a11d2f2c"), "embedded" : [ { "foo" : 1 } ] }
{ "_id" : ObjectId("4f60c52a6fa40267a11d2f30"), "embedded" : [ { "foo" : 1, "bar" : null } ] }
现在,在Morphia中,$elemMatch由FieldEnd方法hasThisElement包装。我不太熟悉我编写的Morphia并使用我自己的映射器,但这应该将带有上述子句的DBObject作为它的值,这应该导致您需要执行的操作

但同样,这将返回顶级文档,这些文档的嵌入数组中包含符合这些条件的元素。如果只想返回匹配的元素,则可能必须在顶级集合中转换嵌入的结构。如果更新仅涉及通过$positional运算符修改匹配元素,则已足够:

db.test.update(
    {embedded:{$elemMatch:{foo:{$exists:true}, $or:[{bar:{$exists:false}}, {bar:null}]}}},
    {$set:{'embedded.$.bar':"yay!"}}
)

我认为您的模式在概念上有问题。请记住,您总是查询顶级文档。查询不起作用的原因是,您要求它返回顶级文档,其中至少一个元素具有foo,而至少一个元素没有bar值。请注意,这两个条件不必应用于同一数组元素

您可以使用$elemMatch在MongoDB中执行您想要的操作:

查找{embedded:{$elemMatch:{foo:{$exists:true},bar:{$exists:false}}},如下所示:

> db.test.save({embedded:[]})
> db.test.save({embedded:[{foo:1}]})
> db.test.save({embedded:[{bar:1}]})
> db.test.save({embedded:[{foo:1, bar:1}]})
> db.test.find({embedded:{$elemMatch:{foo:{$exists:true}, bar:{$exists:false}}}})
{ "_id" : ObjectId("4f60c4d56fa40267a11d2f2c"), "embedded" : [ { "foo" : 1 } ] }
如果null是bar的有效值,您只需将其更改为:

> db.test.save({embedded:[{foo:1, bar:null}]})
> db.test.find({embedded:{$elemMatch:{foo:{$exists:true}, $or:[{bar:{$exists:false}}, {bar:null}]}}})
{ "_id" : ObjectId("4f60c4d56fa40267a11d2f2c"), "embedded" : [ { "foo" : 1 } ] }
{ "_id" : ObjectId("4f60c52a6fa40267a11d2f30"), "embedded" : [ { "foo" : 1, "bar" : null } ] }
现在,在Morphia中,$elemMatch由FieldEnd方法hasThisElement包装。我不太熟悉我编写的Morphia并使用我自己的映射器,但这应该将带有上述子句的DBObject作为它的值,这应该导致您需要执行的操作

但同样,这将返回顶级文档,这些文档的嵌入数组中包含符合这些条件的元素。如果只想返回匹配的元素,则可能必须在顶级集合中转换嵌入的结构。如果更新仅涉及通过$positional运算符修改匹配元素,则已足够:

db.test.update(
    {embedded:{$elemMatch:{foo:{$exists:true}, $or:[{bar:{$exists:false}}, {bar:null}]}}},
    {$set:{'embedded.$.bar':"yay!"}}
)

您要求它返回顶级文档,其中至少一个元素具有foo,并且至少一个元素没有bar值。请注意,这两个条件不必应用于同一数组元素。这正是我想要的——它们不需要在同一个元素上。如果任何条形字段具有值,则上述查询将失败。我想要顶级的收藏,这就足够了。嗯,那样的话,我对你的要求有点不清楚。你能用样本数据和你的查询结果扩展你的原始帖子吗?就像我在回答中所做的那样。它使阅读更容易。你说失败是什么意思?在应该返回结果时不返回结果?投掷错误?在不应该返回结果的时候返回结果?我试图澄清并添加了一个示例。我下面的答案产生了期望的结果……在这种情况下,我的解决方案仍然有效。您必须使用$elemMatch或与之相当的Morphia。这将扫描每个元素,并允许您查询至少一个包含foo但不包含bar但可以包含其他元素的元素
对于$elemMatch,具有两种形式等价物的ts为.hasThisElementvalue。但是,.fieldembedded.bar.hasThisElementnull;阻塞错误,因为该值为空。这可能是一个Morphia问题,而不是与MongoDB相关,但感谢您在数据库级别澄清这一点!您要求它返回顶级文档,其中至少一个元素具有foo,并且至少一个元素没有bar值。请注意,这两个条件不必应用于同一数组元素。这正是我想要的——它们不需要在同一个元素上。如果任何条形字段具有值,则上述查询将失败。我想要顶级的收藏,这就足够了。嗯,那样的话,我对你的要求有点不清楚。你能用样本数据和你的查询结果扩展你的原始帖子吗?就像我在回答中所做的那样。它使阅读更容易。你说失败是什么意思?在应该返回结果时不返回结果?投掷错误?在不应该返回结果的时候返回结果?我试图澄清并添加了一个示例。我下面的答案产生了期望的结果……在这种情况下,我的解决方案仍然有效。您必须使用$elemMatch或与之相当的Morphia。这将扫描每个元素,并允许您查询至少一个包含foo但不包含bar的元素,但可以包含其他元素,这些元素在$elemMatch is.hasThisElementvalue中具有相同的外观。但是,.fieldembedded.bar.hasThisElementnull;阻塞错误,因为该值为空。这可能是一个Morphia问题,而不是与MongoDB相关,但感谢您在数据库级别澄清这一点!