根据对象数组中不匹配的属性查找匹配的文档 - MongoDB

Posted

技术标签:

【中文标题】根据对象数组中不匹配的属性查找匹配的文档 - MongoDB【英文标题】:Find a matching document based on not matching property in array of objects - MongoDB 【发布时间】:2015-01-20 09:40:42 【问题描述】:

我是 MongoDB 或 NoSQL 的新手,我的 Rooms 集合中有一组文档,

/* 1 */

    "roomId" : 1,
    "bookedFor" : [ 
        
            "startTime" : 1000,
            "endTime" : 1100
        , 
        
            "startTime" : 1300,
            "endTime" : 1400
        , 
        
            "startTime" : 1800,
            "endTime" : 1900
        
    ]


/* 2 */

    "roomId" : 3,
    "bookedFor" : [ 
        
            "startTime" : 0900,
            "endTime" : 1000
        , 
        
            "startTime" : 1400,
            "endTime" : 1500
        , 
        
            "startTime" : 1300,
            "endTime" : 1400
        
    ]


/* 3 */

    "roomId" : 2,
    "bookedFor" : [ 
        
            "startTime" : 1000,
            "endTime" : 1100
        , 
        
            "startTime" : 1800,
            "endTime" : 1900
        , 
        
            "startTime" : 0900,
            "endTime" : 1000
        
    ]

现在我想要实现的是,我需要找到一个房间,在请求的时间里应该没有预订。

例如,如果我想预订一个 startTime:1300 和 endTime:1400 的房间,它应该单独返回第三个文档。

P.S:也欢迎任何其他解决我的问题的架构更改。

【问题讨论】:

【参考方案1】:

你可以试试这个

db.yourcollection.find(  bookedFor :  $elemMatch :  startTime : 1300, endTime : 1400    ).sort(  roomId : -1  ).limit(1)

【讨论】:

嗨 Styvane,它没有按我的预期工作。它正在返回已预订 1300 到 1400 的文件。这里还有一个挑战是,即使是 1350 到 1450,它也应该只返回第三个文件,因为时间与之前预订的时间相冲突。 +1 伸出援助之手。 :) 请再次帮助我。 它不工作。因为,您刚刚更新了排序顺序。我的第一个担忧是,它会返回所有预订 1300 - 1400 的文件。但我期望它应该只返回最后一个未预订为 1300 - 1400 的文档。【参考方案2】:

我猜你可以使用 $lg 和 $gt 运算符结合 $or 来计算逻辑。 查找所有未被占用的房间,即没有被占用的房间 1) 在时段开始预订 2) 在时段内预订结束 3) 在时段之前开始和结束之后进行预订 4) 在时段内进行短期预订

在这种情况下将转化为:

db.yourcollection
    .find( bookedFor : 
               $and:[ 
                 $not: $elemMatch : startTime :  $gt : 1300, $lt: 1400 ,
                 $not: $elemMatch : startTime :  $gt : 1300, $lt: 1400 ,
                 $not: $elemMatch : startTime :  $lt : 1300, endTime: $gt: 1400 
                 $not: $elemMatch : startTime :  $gt : 1300, endTime: $lt: 1400 
               ] 
    )

至少在mongo docs 中,elemMatch 也有类似的例子。 这是another link 否定elemMatch。

【讨论】:

以上是关于根据对象数组中不匹配的属性查找匹配的文档 - MongoDB的主要内容,如果未能解决你的问题,请参考以下文章

在对象数组中,查找属性与搜索匹配的对象的索引的最快方法

是否可以根据文档是否包含一组对象来匹配文档?

根据Mongoose中的其他属性返回数组值和分组的匹配记录?

如何在 es6 中仅比较和过滤两个对象数组中不匹配的数组

从数组中查找并返回第一个匹配的子文档(Meteor / Mongo)

循环遍历两个对象数组以将匹配值推送到新数组在 React 中不起作用,但在 JS Fiddle 中起作用