MongoDB: match non-empty doc in array

后端 未结 4 1414
半阙折子戏
半阙折子戏 2021-02-02 07:46

I have a collection structured thusly:

{
  _id: 1,
  score: [
    {
      foo: \'a\',
      bar: 0,
      user: {user1: 0, user2: 7}
    }
  ]
}
<
相关标签:
4条回答
  • 2021-02-02 07:57

    I'm not sure I quite understand your schema, but perhaps the most straight forward way would be to not have an "empty" value for score.user ?

    Instead purposely not have that field in your document if it has no content?

    Then your query could be something like ...

    > db.test.find({ "score" : { "$elemMatch" : { bar : 0, "user" : {"$exists": true }}}})
    

    i.e. looking for a value in score.bar that you want (0 in this case) checking for the mear existence ($exists, see docs) of score.user (and if it has a value, then it'll exist?)

    editied: oops I missed the $elemMatch you had ...

    0 讨论(0)
  • 2021-02-02 08:08

    You probably want to add an auxiliary array that keeps track of the users in the user document:

    {
      _id: 1,
      score: [
        {
          foo: 'a',
          bar: 0,
          users: ["user1", "user2"],
          user: {user1: 0, user2: 7}
        }
      ]
    }
    

    Then you can add new users atomically:

    > db.test.update({_id: 1, score: { $elemMatch: {bar: 0}}},                       
    ... {$set: {'score.$.user.user3': 10}, $addToSet: {'score.$.users': "user3"}})
    

    Remove users:

    > db.test.update({_id: 1, score: { $elemMatch: {bar: 0}}},
    ... {$unset: {'score.$.user.user3': 1}, $pop: {'score.$.users': "user3"}})      
    

    Query scores:

    > db.test.find({_id: 1, score: {$elemMatch: {bar: 0, users: {$not: {$size: 0}}}}})
    

    If you know you'll only be adding non-existent users and removing existent users from the user document, you can simplify users to a counter instead of an array, but the above is more resilient.

    0 讨论(0)
  • 2021-02-02 08:13

    Figured it out: { 'score.user': { "$gt": {} } } will match non-empty docs.

    0 讨论(0)
  • 2021-02-02 08:17

    Look at the $size operator for checking array sizes.

    0 讨论(0)
提交回复
热议问题