MongoDB - 查询操作符:比较查询、逻辑查询、元素查询、数组查询

news2024/9/23 1:39:58

文章目录

    • 1. 构造数据
    • 2. MongoDB 比较查询操作符
      • 1. $eq 等于
        • 1.1 等于指定值
        • 1.2 嵌入式文档中的字段等于某个值
        • 1.3 数组元素等于某个值
        • 1.4 数组元素等于数组值
      • 2. $ne 不等于
      • 3. $gt 大于
        • 3.1 匹配文档字段
        • 3.2 根据嵌入式文档字段执行更新
      • 4. $gte 大于等于
      • 5. $lt 小于
      • 6. $lte 小于等于
      • 7. $in
      • 8. $nin
    • 3. MongoDB 逻辑查询操作符
      • 1. $and
      • 2. $or
      • 3. $not
      • 4. $nor
    • 4. 元素查询操作符
      • 1. $exists
      • 2. $type
    • 5. MongoDB 数组查询操作符
      • 1. $elemMatch
        • 1.1 元素匹配
        • 1.2 嵌入式文档数组
      • 2. $size
      • 3. $all

参考官方文档:https://www.mongodb.com/zh-cn/docs/manual/reference/operator/query/and/

1. 构造数据

① 批量插入4个文档到user集合:

db.user.insertMany([
  { name: "Alice", age: 25, email: "alice@example.com", hobbies: ["reading", "writing", "music"] },
  { name: "John", age: 30, email: "John@qq.com", hobbies: ["reading", "gaming", "traveling"] },
  { name: "Jane", age: 25, email: "Jane@qq.com", hobbies: ["sports", "music", "cooking"] },
  { name: "Mike", age: 35, email: "Mike@qq.com", hobbies: ["reading", "writing", "painting"] }
]);

② SpringBoot整合MongoDB实现批量插入文档:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
@AllArgsConstructor
@NoArgsConstructor
@Data
@Document(collection = "user")
public class User {
    @Id
    private String id;
    private String name;
    private Integer age;
    private String email;
    private List<String> hobbies;

    public User(String name,Integer age,String email,List<String> hobbies){
        this.name = name;
        this.age = age;
        this.email = email;
        this.hobbies = hobbies;
    }
}
@SpringBootTest
@RunWith(SpringRunner.class)
public class BeanLoadServiceTest {

    @Autowired
    private MongoTemplate mongoTemplate;

    @Test
    public void insertUser() {
        List<User> users = Arrays.asList(
                new User("Alice", 25, "alice@example.com",Arrays.asList("reading", "writing", "music")),
                new User("John", 30, "John@qq.com", Arrays.asList("reading", "gaming", "traveling")),
                new User("Jane", 25, "Jane@qq.com", Arrays.asList("sports", "music", "cooking")),
                new User("Mike", 35, "Mike@qq.com", Arrays.asList("reading", "writing", "painting"))
        );
        mongoTemplate.insertAll(users);
    }
}

在这里插入图片描述

2. MongoDB 比较查询操作符

比较操作符根据数值比较返回数据。MongoDB提供了一些比较查询操作符,用于在查询中进行条件比较。以下是一些常用的比较查询操作符:

$eq:等于,用于匹配字段值等于指定值的文档。
例如:db.collection.find({ field: { $eq: value } })

$ne:不等于,用于匹配字段值不等于指定值的文档。
例如:db.collection.find({ field: { $ne: value } })

$gt:大于,用于匹配字段值大于指定值的文档。
例如:db.collection.find({ field: { $gt: value } })

$gte:大于等于,用于匹配字段值大于等于指定值的文档。
例如:db.collection.find({ field: { $gte: value } })

$lt:小于,用于匹配字段值小于指定值的文档。
例如:db.collection.find({ field: { $lt: value } })

$lte:小于等于,用于匹配字段值小于等于指定值的文档。
例如:db.collection.find({ field: { $lte: value } })

$in:在指定值数组中,用于匹配字段值在指定值数组中的文档。
例如:db.collection.find({ field: { $in: [value1, value2, …] } })

$nin:不在指定值数组中,用于匹配字段值不在指定值数组中的文档。
例如:db.collection.find({ field: { $nin: [value1, value2, …] } })

这些比较查询操作符可以与逻辑操作符(如 a n d 、 and、 andor、$not等)结合使用,以构建更复杂的查询条件。

1. $eq 等于

用于匹配字段值等于指定值的文档:

db.collection.find({ field: { $eq: value } })
# 相当于
db.collection.find({ field : value})
1.1 等于指定值

查询user集合中name等于Alice的文档:

db.user.find({ name: { $eq: "Alice" } })
@Test
public void findUser1() {
    // 创建查询条件
    Criteria criteria = Criteria.where("name").is("Alice");
    // 创建查询对象
    Query query = new Query(criteria);
    // 执行查询
    List<User> users = mongoTemplate.find(query, User.class);
    
    users.forEach(System.out::println); 
	// User(id=668f53342e9dde5bccea0096, name=Alice, age=25, email=alice@example.com, hobbies=[reading, writing, music])
}
1.2 嵌入式文档中的字段等于某个值
db.inventory.insertMany( [
   { _id: 1, item: { name: "ab", code: "123" }, qty: 15, tags: [ "A", "B", "C" ] },
   { _id: 2, item: { name: "cd", code: "123" }, qty: 20, tags: [ "B" ] },
   { _id: 3, item: { name: "ij", code: "456" }, qty: 25, tags: [ "A", "B" ] },
   { _id: 4, item: { name: "xy", code: "456" }, qty: 30, tags: [ "B", "A" ] },
   { _id: 5, item: { name: "mn", code: "000" }, qty: 20, tags: [ [ "A", "B" ], "C" ] }
] )

查询 inventory 集合中 item 文档的 name 等于 "ab" 的所有文档。要对嵌入式文档中的字段指定条件,使用点符号:

db.inventory.find( { "item.name": { $eq: "ab" } } )
@Data
@Document(collection = "inventory")
public class Inventory {
    @Id
    private String id;
    private Item item;
    private int qty;
    private List<Object> tags;

    @Data
    public static class Item {
        private String name;
        private String code;
    }
}

@Test
public void findUser1() {
    // 创建查询条件
    Criteria criteria = Criteria.where("item.name").is("ab");
    // 创建查询对象
    Query query = new Query(criteria);
    List<Inventory> inventoryList = mongoTemplate.find(query, Inventory.class);

    inventoryList.forEach(System.out::println);
    // Inventory(id=1.0, item=Inventory.Item(name=ab, code=123), qty=15, tags=[A, B, C])
}
1.3 数组元素等于某个值

查询 inventory 集合中 tags 数组包含值为 "C" 的元素的所有文档:

db.inventory.find( { tags: { $eq: "B" } } )
@Test
public void findUser1() {
    // 创建查询条件
    Criteria criteria = Criteria.where("tags").is("C");
    // 创建查询对象
    Query query = new Query(criteria);
    List<Inventory> inventoryList = mongoTemplate.find(query, Inventory.class);

    inventoryList.forEach(System.out::println);
    // Inventory(id=1.0, item=Inventory.Item(name=ab, code=123), qty=15, tags=[A, B, C])
    // Inventory(id=5.0, item=Inventory.Item(name=mn, code=000), qty=20, tags=[[A, B], C])
}
1.4 数组元素等于数组值

查询 inventory 集合中 tags 数组与指定数组完全相同或 tags 数组包含数组 [ "A", "B" ] 的所有文档:

db.inventory.find( { tags: { $eq: [ "A", "B" ] } } )
db.inventory.find( { tags: [ "A", "B" ] } )
@Test
public void findUser1() {
    // 创建查询条件
    Criteria criteria = Criteria.where("tags").is(Arrays.asList("A","B"));
    // 创建查询对象
    Query query = new Query(criteria);
    List<Inventory> inventoryList = mongoTemplate.find(query, Inventory.class);

    inventoryList.forEach(System.out::println);
    // Inventory(id=3.0, item=Inventory.Item(name=ij, code=456), qty=25, tags=[A, B])
    // Inventory(id=5.0, item=Inventory.Item(name=mn, code=000), qty=20, tags=[[A, B], C])
}

2. $ne 不等于

用于匹配字段值不等于指定值的文档:

db.collection.find({ field: { $ne: value } })

查询user集合中name不等于Alice的文档:

db.user.find({ name: { $ne: "Alice" } })
@Test
public void findUser2() {
    // 创建查询条件
    Criteria criteria = Criteria.where("name").ne("Alice");
    // 创建查询对象
    Query query = new Query(criteria);
    // 执行查询
    List<User> users = mongoTemplate.find(query, User.class);
    
    users.forEach(System.out::println);
    // User(id=668f53342e9dde5bccea0097, name=John, age=30, email=John@qq.com, hobbies=[reading, gaming, traveling])
    // User(id=668f53342e9dde5bccea0098, name=Jane, age=25, email=Jane@qq.com, hobbies=[sports, music, cooking])
    // User(id=668f53342e9dde5bccea0099, name=Mike, age=35, email=Mike@qq.com, hobbies=[reading, writing, painting])
}

3. $gt 大于

用于匹配字段值大于指定值的文档:

db.collection.find({ field: { $gt: value } })
3.1 匹配文档字段

查询user集合中age大于30的文档:

@Test
public void findUser2() {
    // 创建查询条件
    Criteria criteria = Criteria.where("age").gt(30);
    // 创建查询对象
    Query query = new Query(criteria);
    // 执行查询
    List<User> users = mongoTemplate.find(query, User.class);
    
    users.forEach(System.out::println);
    // User(id=668f53342e9dde5bccea0099, name=Mike, age=35, email=Mike@qq.com, hobbies=[reading, writing, painting])
}
3.2 根据嵌入式文档字段执行更新
db.inventory.insertMany( [
   {
      "item": "nuts", "quantity": 30,
      "carrier": { "name": "Shipit", "fee": 3 }
   },
   {
      "item": "bolts", "quantity": 50,
      "carrier": { "name": "Shipit", "fee": 4 }
   },
   {
      "item": "washers", "quantity": 10,
      "carrier": { "name": "Shipit", "fee": 1 }
   }
] )

查询 inventory 集合中 carrier 文档的 fee 大于 2 的第一个文档,并设置文档的price等于9.99:

db.inventory.updateOne(
   { "carrier.fee": { $gt: 2 } }, { $set: { "price": 9.99 } }
)
@Data
@Document(collection = "inventory")
public class Inventory {
    @Id
    private String id;
    private String item;
    private int quantity;
    private Carrier carrier;

    @Data
    public static class Carrier {
        private String name;
        private int fee;
    }
}

@Test
public void updateUser(){
    // 创建查询条件
    Criteria criteria = Criteria.where("carrier.fee").gt(2);
    // 创建更新对象
    Update update = new Update();
    update.set("price", 9.99);
    // 创建查询对象
    Query query = new Query(criteria);
    // 执行更新操作
    UpdateResult updateResult = mongoTemplate.updateFirst(query, update, Inventory.class);
}

对应查询结果为:

{
  _id: ObjectId("61ba3ec9fe687fce2f042417"),
  item: 'nuts',
  quantity: 30,
  carrier: { name: 'Shipit', fee: 3 },
  price: 9.99
},
{
  _id: ObjectId("61ba3ec9fe687fce2f042418"),
  item: 'bolts',
  quantity: 50,
  carrier: { name: 'Shipit', fee: 4 }
},
{
  _id: ObjectId("61ba3ec9fe687fce2f042419"),
  item: 'washers',
  quantity: 10,
  carrier: { name: 'Shipit', fee: 1 }
}

要在carrier.fee 所有大于 2 的文档中设置 price 字段的值,请使用 updateMany()

4. $gte 大于等于

用于匹配字段值大于等于指定值的文档:

db.collection.find({ field: { $gte: value } })

查询user集合中age大于等于30的文档:

@Test
public void findUser2() {
    // 创建查询条件
    Criteria criteria = Criteria.where("age").gte(30);
    // 创建查询对象
    Query query = new Query(criteria);
    // 执行查询
    List<User> users = mongoTemplate.find(query, User.class);

    users.forEach(System.out::println);
    // User(id=668f53342e9dde5bccea0097, name=John, age=30, email=John@qq.com, hobbies=[reading, gaming, traveling])
    // User(id=668f53342e9dde5bccea0099, name=Mike, age=35, email=Mike@qq.com, hobbies=[reading, writing, painting])
}

5. $lt 小于

用于匹配字段值小于指定值的文档:

db.collection.find({ field: { $lt: value } })

查询user集合中age小于30的文档:

@Test
public void findUser1() {
    // 创建查询条件
    Criteria criteria = Criteria.where("age").lt(30);
    // 创建查询对象
    Query query = new Query(criteria);
    // 执行查询
    List<User> users = mongoTemplate.find(query, User.class);

    users.forEach(System.out::println);
    // User(id=668f53342e9dde5bccea0096, name=Alice, age=25, email=alice@example.com, hobbies=[reading, writing, music])
    // User(id=668f53342e9dde5bccea0098, name=Jane, age=25, email=Jane@qq.com, hobbies=[sports, music, cooking])
}

6. $lte 小于等于

用于匹配字段值小于等于指定值的文档:

db.collection.find({ field: { $lte: value } })

查询user集合中age小于等于30的文档:

@Test
public void findUser2() {
    // 创建查询条件
    Criteria criteria = Criteria.where("age").lte(30);
    // 创建查询对象
    Query query = new Query(criteria);
    // 执行查询
    List<User> users = mongoTemplate.find(query, User.class);

    users.forEach(System.out::println);
    // User(id=668f53342e9dde5bccea0096, name=Alice, age=25, email=alice@example.com, hobbies=[reading, writing, music])
    // User(id=668f53342e9dde5bccea0097, name=John, age=30, email=John@qq.com, hobbies=[reading, gaming, traveling])
    // User(id=668f53342e9dde5bccea0098, name=Jane, age=25, email=Jane@qq.com, hobbies=[sports, music, cooking])
}

7. $in

在指定值数组中,用于匹配字段值在指定值数组中的文档:

db.collection.find({ field: { $in: [value1, value2, ...] } })

查询user集合中name等于Alice或Jone或Jane的文档:

db.user.find({ name: { $in: ["Alice", "John", "Jane"] } })
@Test
public void findUser2() {
    // 创建查询条件
    Criteria criteria = Criteria.where("name").in(Arrays.asList("Alice","John","Jane"));
    // 创建查询对象
    Query query = new Query(criteria);
    // 执行查询
    List<User> users = mongoTemplate.find(query, User.class);

    users.forEach(System.out::println);
    // User(id=668f53342e9dde5bccea0096, name=Alice, age=25, email=alice@example.com, hobbies=[reading, writing, music])
    // User(id=668f53342e9dde5bccea0097, name=John, age=30, email=John@qq.com, hobbies=[reading, gaming, traveling])
    // User(id=668f53342e9dde5bccea0098, name=Jane, age=25, email=Jane@qq.com, hobbies=[sports, music, cooking])
}

8. $nin

不在指定值数组中,用于匹配字段值不在指定值数组中的文档:

db.collection.find({ field: { $nin: [value1, value2, ...] } })

查询user集合中name不等于Alice、Jone、Jane的文档:

db.user.find({ name: { $nin: ["Alice", "John", "Jane"] } })
@Test
public void findUser2() {
    // 创建查询条件
    Criteria criteria = Criteria.where("name").nin(Arrays.asList("Alice","John","Jane"));
    // 创建查询对象
    Query query = new Query(criteria);
    // 执行查询
    List<User> users = mongoTemplate.find(query, User.class);

    users.forEach(System.out::println);
    // User(id=668f53342e9dde5bccea0099, name=Mike, age=35, email=Mike@qq.com, hobbies=[reading, writing, painting])
}

3. MongoDB 逻辑查询操作符

逻辑操作符根据计算结果为 ture 或 false 的表达式来返回数据。MongoDB提供了丰富的逻辑查询操作符,用于在查询中进行逻辑运算和条件判断。以下是一些常用的逻辑查询操作符:

$and:用于同时满足多个条件的查询。
例如:db.collection.find({ $and: [ { condition1 }, { condition2 } ] })

$or:用于满足多个条件中的任意一个的查询。
例如:db.collection.find({ $or: [ { condition1 }, { condition2 } ] })

$not:用于否定一个条件的查询。
例如:db.collection.find({ field: { $not: { condition } } })

$nor:用于满足多个条件都不成立的查询。
例如:db.collection.find({ $nor: [ { condition1 }, { condition2 } ] })

这些逻辑查询操作符可以与其他查询条件结合使用,以实现更复杂的查询逻辑。

1. $and

用于同时满足多个条件的查询。

db.collection.find({ $and: [ { condition1 }, { condition2 } ] })

查询user集合中age大于等于18,并且name等于Alice的文档:

db.user.find({ $and: [ { age: { $gte: 18 } }, { name: "Alice" } ] })
@Test
public void findUser1() {
    // 创建查询条件:首先创建了一个Criteria对象,并使用andOperator方法来添加多个条件
    Criteria criteria = new Criteria();
    criteria.andOperator(
            Criteria.where("age").gte(18),
            Criteria.where("name").is("Alice")
    );
    // 创建查询对象
    Query query = new Query(criteria);
    // 执行查询
    List<User> users = mongoTemplate.find(query, User.class);

    users.forEach(System.out::println);
    // User(id=668f53342e9dde5bccea0096, name=Alice, age=25, email=alice@example.com, hobbies=[reading, writing, music])
}
@Test
public void findUser1() {
    // 查询条件
    Criteria criteria =  Criteria.where("age").gte(18).and("name").is("Alice");
    // 查询对象
    Query query = new Query();
    query.addCriteria(criteria);
    // 执行查询
    List<User> users = mongoTemplate.find(query, User.class);

    users.forEach(System.out::println);
    // User(id=668f53342e9dde5bccea0096, name=Alice, age=25, email=alice@example.com, hobbies=[reading, writing, music])
}

2. $or

用于满足多个条件中的任意一个的查询。

db.collection.find({ $or: [ { condition1 }, { condition2 } ] })

查询user集合中age小于30,或者name等于Alice的文档:

db.user.find({ $or: [ { age: { gt: 30 } }, { name: "Alice" } ] })
@Test
public void findUser1() {
    // 创建查询条件
    Criteria criteria = new Criteria();
    // 首先创建了一个Criteria对象,并使用orOperator方法来添加多个条件
    criteria.orOperator(
        Criteria.where("age").gt(30),
        Criteria.where("name").is("Alice")
    );
    // 创建查询对象
    Query query = new Query(criteria);
    // 执行查询
    List<User> users = mongoTemplate.find(query, User.class);

    users.forEach(System.out::println);
    // User(id=668f53342e9dde5bccea0096, name=Alice, age=25, email=alice@example.com, hobbies=[reading, writing, music])
    // User(id=668f53342e9dde5bccea0099, name=Mike, age=35, email=Mike@qq.com, hobbies=[reading, writing, painting])
}

3. $not

用于否定一个条件的查询。

db.collection.find({ field: { $not: { condition } } })

查询user集合中age小于30的文档:

db.user.find({ age: { $not: { $gte: 30 } } })
@Test
public void findUser1() {
    // 创建查询对象
    Query query = new Query(Criteria.where("age").not().gte(30));
    // 执行查询
    List<User> users = mongoTemplate.find(query, User.class);

    users.forEach(System.out::println);
    // User(id=668f53342e9dde5bccea0096, name=Alice, age=25, email=alice@example.com, hobbies=[reading, writing, music])
    // User(id=668f53342e9dde5bccea0098, name=Jane, age=25, email=Jane@qq.com, hobbies=[sports, music, cooking])
}

4. $nor

用于满足多个条件都不成立的查询。

db.collection.find({ $nor: [ { condition1 }, { condition2 } ] })

查询user集合中age小于30,并且name不等于Alice的文档

db.users.find({ $nor: [ { age: { $gte: 30 } }, { name: "Alice" } ] })
@Test
public void findUser1() {
    Criteria criteria = new Criteria();
    criteria.norOperator(
            Criteria.where("age").gte(30),
            Criteria.where("name").is("Alice")
    );
    // 创建查询对象
    Query query = new Query(criteria);
    // 执行查询
    List<User> users = mongoTemplate.find(query, User.class);

    users.forEach(System.out::println);
    // User(id=668f53342e9dde5bccea0098, name=Jane, age=25, email=Jane@qq.com, hobbies=[sports, music, cooking])
}

4. 元素查询操作符

元素操作符根据字段是否存在或数据类型返回数据。

$exists:用于检查字段是否存在的查询。
例如:db.collection.find({ field: { $exists: true } })

$type:用于检查字段类型的查询。
例如:db.collection.find({ field: { $type: “string” } })

数据构造:向user集合中name等于Alice的文档新增一个字段

db.user.updateOne( 
    { name: "Alice" },
    {
      $set: {city: "ShangHai"}
    }
)
@Test
public void updateUser(){
    // 构建查询条件
    Criteria criteria = Criteria.where("name").is("Alice");
    Query query = Query.query(criteria);

    // 构建更新操作
    Update update = new Update();
    update.set("city", "ShangHai");

    // 执行更新操作
    mongoTemplate.updateMulti(query, update, "user");
}

在这里插入图片描述

1. $exists

用于检查字段是否存在的查询

db.collection.find({ field: { $exists: true } })

查询user集合中city字段是否存在:

db.user.find({ city: { $exists: true } })
@Test
public void findUser1() {
    // 查询条件
    Criteria criteria = Criteria.where("city").exists(true);
    // 查询对象
    Query query = new Query(criteria);
    // 执行查询
    List<User> users = mongoTemplate.find(query, User.class);
    
    users.forEach(System.out::println);
    // User(id=668f53342e9dde5bccea0096, name=Alice, age=25, email=alice@example.com, hobbies=[reading, writing, music])
}

2. $type

用于检查字段类型的查询

db.collection.find({ field: { $type: "string" } })

$type 运算符接受的字段类型:

类型数值别名注意
双精度1“double”
字符串2“string”
对象3“object”
阵列4“array”
二进制数据5“binData”
ObjectId7“objectId”
布尔8“bool”
Date9“date”
null10“null”
正则表达式11“regex”
JavaScript13“javascript”
32 位整数16“int”
时间戳17“timestamp”
64 位整型18“long”
Decimal12819“decimal”
Min key-1“minKey”
Max key127“maxKey”

查询user集合中name的字段类型是否为string:

db.user.find({ name: { $type: "string" } })
db.user.find( { name : { $type : 2 } } ) 
@Test
public void findUser1() {
    // 查询条件
    Criteria criteria =  Criteria.where("name").type(2);
    // 查询对象
    Query query = new Query(criteria);
    // 执行查询
    List<User> users = mongoTemplate.find(query, User.class);

    users.forEach(System.out::println);
    // User(id=668f53342e9dde5bccea0096, name=Alice, age=25, email=alice@example.com, hobbies=[reading, writing, music])
    // User(id=668f53342e9dde5bccea0097, name=John, age=30, email=John@qq.com, hobbies=[reading, gaming, traveling])
    // User(id=668f53342e9dde5bccea0098, name=Jane, age=25, email=Jane@qq.com, hobbies=[sports, music, cooking])
    // User(id=668f53342e9dde5bccea0099, name=Mike, age=35, email=Mike@qq.com, hobbies=[reading, writing, painting])
}

5. MongoDB 数组查询操作符

数组操作符根据数组条件返回数据。MongoDB提供了多种数组查询操作符,用于在查询中对数组字段进行操作和匹配。以下是一些常用的数组查询操作符:

$elemMatch:用于在数组字段中匹配满足多个条件的元素的查询。
db.collection.find({ field: { $elemMatch: { condition1, condition2 } } })

$size:用于匹配数组字段的长度的查询。
db.collection.find({ field: { $size: 3 } })

$all:用于匹配数组字段中包含所有指定元素的查询。
db.collection.find({ field: { $all: [ element1, element2 ] } })

$in:用于匹配数组字段中包含指定元素的查询。例如:

db.collection.find({ field: { $in: [ element1, element2 ] } })
$nin:用于匹配数组字段中不包含指定元素的查询。例如:

db.collection.find({ field: { $nin: [ element1, element2 ] } })
$slice:用于返回数组字段的子集。例如:

db.collection.find({ field: { $slice: 5 } })
$addToSet:用于向数组字段添加唯一的元素。例如:

db.collection.updateOne({ _id: ObjectId(“…”) }, { $addToSet: { field: element } })
这些数组查询操作符可以与其他查询条件结合使用,以实现更复杂的查询逻辑。请注意,以上示例中的"collection"和"field"应替换为实际的集合名和字段名。

1. $elemMatch

用于在数组字段中匹配满足多个条件的元素的查询。

db.collection.find({ arrayField: { $elemMatch: { condition1, condition2 } } })
1.1 元素匹配

查询user集合中age大于等于30并且hobbies包含reading的文档:

db.user.find({ age: { $gte: 30 }, hobbies: { $elemMatch: { $eq: "reading" } } })
@Test
public void findUser1() {
    // 查询条件
    Criteria criteria =  Criteria.where("age").gte(30).and("hobbies").elemMatch(Criteria.where("$eq").is("reading"));
    // 查询对象
    Query query = new Query(criteria);
    // 执行查询
    List<User> users = mongoTemplate.find(query, User.class);

    users.forEach(System.out::println);
    // User(id=668f53342e9dde5bccea0097, name=John, age=30, email=John@qq.com, hobbies=[reading, gaming, traveling])
    // User(id=668f53342e9dde5bccea0099, name=Mike, age=35, email=Mike@qq.com, hobbies=[reading, writing, painting])
}
@Test
public void findUser1() {
    // 查询条件
    Criteria criteria =  new Criteria();
    criteria.andOperator(
            Criteria.where("age").gte(30),
            Criteria.where("hobbies").elemMatch(Criteria.where("$eq").is("reading"))
    );
    // 查询对象
    Query query = new Query();
    query.addCriteria(criteria);
    // 执行查询
    List<User> users = mongoTemplate.find(query, User.class);

    users.forEach(System.out::println);
    // User(id=668f53342e9dde5bccea0097, name=John, age=30, email=John@qq.com, hobbies=[reading, gaming, traveling])
    // User(id=668f53342e9dde5bccea0099, name=Mike, age=35, email=Mike@qq.com, hobbies=[reading, writing, painting])
}

查询user集合中hobbies数组包含reading的文档:

db.user.find( hobbies: { $elemMatch: { $eq: "reading" } } })
@Test
public void findUser1() {
    // 查询条件
    Criteria criteria =  Criteria.where("hobbies").elemMatch(Criteria.where("$eq").is("reading"));
    // 查询对象
    Query query = new Query();
    query.addCriteria(criteria);
    // 执行查询
    List<User> users = mongoTemplate.find(query, User.class);

    users.forEach(System.out::println);
    // User(id=668f53342e9dde5bccea0096, name=Alice, age=25, email=alice@example.com, hobbies=[reading, writing, music])
    //User(id=668f53342e9dde5bccea0097, name=John, age=30, email=John@qq.com, hobbies=[reading, gaming, traveling])
    //User(id=668f53342e9dde5bccea0099, name=Mike, age=35, email=Mike@qq.com, hobbies=[reading, writing, painting])
}
1.2 嵌入式文档数组

① 查询survey集合中product"xyz"score大于或等于8 的文档:

db.survey.insertMany( [
   { "_id": 1, "results": [ { "product": "abc", "score": 10 },{ "product": "xyz", "score": 5 } ] },
   { "_id": 2, "results": [ { "product": "abc", "score": 8 },{ "product": "xyz", "score": 7 } ] },
   { "_id": 3, "results": [ { "product": "abc", "score": 7 },{ "product": "xyz", "score": 8 } ] },
   { "_id": 4, "results": [ { "product": "abc", "score": 7 },{ "product": "def", "score": 8 } ] },
   { "_id": 5, "results": { "product": "xyz", "score": 9 } }
] )

注意,_id5 的文档不包含数组。

db.survey.find( { results: { $elemMatch: { product: "xyz", score: { $gte: 8 } } } } )
@Data
@Document(collection = "survey")
public class Survey {
    @Id
    private int _id;
    private List<Result> results;
}

@Data
public class  Result {
    private String product;
    private int score;
}

@Test
public void findUser1() {
    // 查询条件
    Query query = new Query();
    query.addCriteria(Criteria.where("results").elemMatch(
        Criteria.where("product").is("xyz").and("score").gte(8)
    ));
    List<Survey> surveyList = mongoTemplate.find(query, Survey.class, "survey");

    surveyList.forEach(System.out::println);
    // Survey(_id=3, results=[Result(product=abc, score=7), Result(product=xyz, score=8)])
}

② 使用$elemMatch进行单一查询条件:

db.survey.find(
   { results: { $elemMatch: { product: "xyz" } } }
)

此查询会返回 results 中的任一 product"xyz" 的文档。

③ 不使用$elemMatch进行单一查询条件:

db.survey.find(
   { "results.product": "xyz" }
)

此查询结果还包括 _id5 的文档(不包含数组)

④ 查询student集合中所有数学成绩高于90分的学生:

db.student.insertMany( 
    [
      {"_id": 1,
			"name": "Alice",
			"grades": [
          { "subject": "Math", "score": 90 },
          { "subject": "English", "score": 85 },
          { "subject": "Science", "score": 95 }
        ]
      },
      {
        "_id": 2,
				"name": "Bob",
				"grades": [
          { "subject": "Math", "score": 80 },
          { "subject": "English", "score": 75 },
          { "subject": "Science", "score": 85 }
        ]
      },
      {
        "_id": 3, 
				"name": "Charlie",
				"grades": [
          { "subject": "Math", "score": 95 },
          { "subject": "English", "score": 90 },
          { "subject": "Science", "score": 92 }
        ]
      }
    ]
)
db.students.find({ grades: { $elemMatch: { subject: "Math", score: { $gt: 90 } } } })
@Data
@Document(collection = "student")
public class Student {
    @Id
    private int _id;
    private String name;
    private List<Grade> grades;
}

@Data
public class Grade {
    private String subject;
    private int score;
}

@Test
public void findUser1() {
    // 查询条件
    Query query = new Query();
    query.addCriteria(Criteria.where("grades").elemMatch(
        Criteria.where("subject").is("Math").and("score").gte(90)
    ));
    List<Student> studentList = mongoTemplate.find(query, Student.class, "student");

    studentList.forEach(System.out::println);
    // Student(_id=1, name=Alice, grades=[Grade(subject=Math, score=90), Grade(subject=English, score=85), Grade(subject=Science, score=95)])
    // Student(_id=3, name=Charlie, grades=[Grade(subject=Math, score=95), Grade(subject=English, score=90), Grade(subject=Science, score=92)])
}

2. $size

用于匹配数组字段的长度的查询。

db.collection.find({ arrayField: { $size: 3 } })

查询user集合中hobbies数组包含2个元素的所有文档:

db.user.insertMany([
  { name: "Alice", age: 25, email: "alice@example.com", hobbies: ["writing"] },
  { name: "John", age: 30, email: "John@qq.com", hobbies: ["reading", "gaming",] },
  { name: "Jane", age: 25, email: "Jane@qq.com", hobbies: ["sports", "music"] },
  { name: "Mike", age: 35, email: "Mike@qq.com", hobbies: ["reading", "writing", "painting", "cooking"] }
]);
db.user.find( { hobbies: { $size: 2 } } );
@Test
public void findUser1() {
    // 查询条件
    Query  query = new Query();
    Criteria criteria = Criteria.where("hobbies").size(2);
    query.addCriteria(criteria);

    List<User> users = mongoTemplate.find(query, User.class, "user");
    
    users.forEach(System.out::println);
    // User(id=66906798197700004d003dcd, name=John, age=30, email=John@qq.com, hobbies=[reading, gaming])
    //User(id=66906798197700004d003dce, name=Jane, age=25, email=Jane@qq.com, hobbies=[sports, music])
}

此查询返回 collectionfield 为包含 2 个元素的数组的所有文档。

3. $all

用于匹配数组字段中包含所有指定元素的查询。

db.collection.find({ field: { $all: [ element1, element2 ] } })
db.user.insertMany([
  { name: "Alice", age: 25, email: "alice@example.com", hobbies: ["reading", "writing", "music"] },
  { name: "John", age: 30, email: "John@qq.com", hobbies: ["reading", "gaming", "traveling"] },
  { name: "Jane", age: 25, email: "Jane@qq.com", hobbies: ["sports", "music", "cooking"] },
  { name: "Mike", age: 35, email: "Mike@qq.com", hobbies: ["reading", "writing", "painting"] }
]);

查询user集合中hobbies数组包含 “writing” 和 “music” 的文档:

db.user.find({ hobbies: { $all: [ "writing" , "music" ] } })
# 相当于
db.user.find({ $and: [ { hobbies: "writing" }, { hobbies: "music" } ] })
@Test
public void findUser1() {
    // 查询条件
    Query  query = new Query();
    Criteria criteria = Criteria.where("hobbies").all("music","writing");
    query.addCriteria(criteria);

    List<User> users = mongoTemplate.find(query, User.class, "user");

    users.forEach(System.out::println);
    // User(id=6690693d197700004d003dd0, name=Alice, age=25, email=alice@example.com, hobbies=[reading, writing, music])
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1922662.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

(Vue+SpringBoot+elementUi+WangEditer)仿论坛项目

项目使用到的技术与库 1.前端 Vue2 elementUi Cookie WangEditer 2.后端 SpringBoot Mybatis-Plus 3.数据库 MySql 一、效果展示 1.1主页效果&#xff1a; 1.2 文章编辑页面&#xff1a; 1.3 成功发布文章 1.4 文章关键字搜索提示 1.5 文章查询结果展示 1.6 文章内容及交互展示…

统信UOS服务器操作系统离线安装postgresql数据库

原文链接&#xff1a;统信UOS服务器离线安装postgresql数据库 Hello&#xff0c;大家好啊&#xff01;今天给大家带来一篇关于在统信UOS服务器操作系统上离线安装PostgreSQL数据库的文章。PostgreSQL是一款功能强大的开源对象-关系型数据库管理系统。由于某些环境中无法直接访问…

免费开源的工业物联网(IoT)解决方案

什么是 IoT&#xff1f; 物联网 (IoT) 是指由实体设备、车辆、电器和其他实体对象组成的网络&#xff0c;这些实体对象内嵌传感器、软件和网络连接&#xff0c;可以收集和共享数据。 IoT 设备&#xff08;也称为“智能对象”&#xff09;范围广泛&#xff0c;包括智能恒温器等…

SpringBoot+Vue(2)excel后台管理页面

一、需求 SpringBootVue写excel后台管理页面&#xff08;二级页面打开展示每一个excel表&#xff0c;数据库存储字段为“下载、删除、文件详情、是否共享、共享详情”&#xff09; 二、解答 后端(Spring Boot) 1. 项目设置 使用Spring Initializr创建一个新的Spring Boot项目…

深入理解 Elasticsearch 分页技术

原文链接&#xff1a;https://zhuanlan.zhihu.com/p/609576187 Elasticsearch 是一款分布式的搜索引擎&#xff0c;提供了灵活的分页技术。本文主要介绍 Elasticsearch&#xff08;简称 ES&#xff09; 的几种分页技术&#xff0c;并深入分析各种分页技术的优缺点及应用场景。 …

基于AT89C51单片机篮球计时计分器的设计(含文档、源码与proteus仿真,以及系统详细介绍)

本篇文章论述的是基于AT89C51单片机篮球计时计分器的设计的详情介绍&#xff0c;如果对您有帮助的话&#xff0c;还请关注一下哦&#xff0c;如果有资源方面的需要可以联系我。 目录 绪论 原理图 ​编辑 仿真图 系统总体设计图 代码实现 系统论文 资源下载 绪论 本次…

内网服务器通过squid代理访问外网

一、背景 现在要对172.16.58.158服务器进行openssh升级操作,我用之前写好的升级脚本执行后,发现没有备份旧的ssh程序文件,然后还卸载了oenssl-devel,然后我发现其他服务器ssh该服务器失败。同时脚本执行时报错“ configure: error: *** zlib.h missing - please install first …

windows查看局域网所有设备ip

windows如何查看局域网所有设备ip 操作方法 一 . 在搜索栏里输入cmd 二 .在命令行黑窗口输入arp -a 三 . 最上面显示的动态地址就是所有设备ip

day20、21、22补卡

235. 二叉搜索树的最近公共祖先 这道题的解题思路&#xff0c;我想了一会都没想出来&#xff0c;看了题解想&#xff1a;对于二叉搜索树&#xff0c;当我们从上向下去递归遍历&#xff0c;第一次遇到 cur节点是数值在[q, p]区间中&#xff0c;那么cur就是 q和p的最近公共祖先。…

Database数据库 vs Data Warehouse数据仓库 vs Data Mart数据集市 vs Data Lake数据湖

1.DATABASE 数据库 数据库是一个结构化的数据集合&#xff0c;用于存储、管理和检索数据。数据库设计用于支持事务处理&#xff08;OLTP&#xff0c;Online Transaction Processing&#xff09;和日常操作。 数据库通常由数据库管理系统&#xff08;DBMS&#xff09;控制&…

webRtc架构与目录结构

整体架构 目录结构 webrtc Modules目录

基于PCIe总线架构的2路1GSPS AD、4路1GSPS DA信号处理平台(100%国产化)

板卡概述 PCIE723-165是基于PCIE总线架构的2通道1GSPS采样率14位分辨率、4通道1GSPS采样率16位分辨率信号处理平台&#xff0c;该板卡采用国产16nm FPGA作为实时处理器&#xff0c;支持2路高速采集以及4路高速数据回放&#xff0c;板载2组DDR4 SDRAM大容量数据缓存&#xff0c;…

宝兰德参编金融智能体标准,深耕大模型场景化落地

随着数智化浪潮的不断推进&#xff0c;人工智能技术正深刻影响着金融服务的模式和流程&#xff0c;金融智能体在大模型的加持下&#xff0c;业务场景的应用能力得到强化。然而&#xff0c;作为新型技术&#xff0c;金融智能体在隐私保护、透明性、数据泄露等方面仍存在诸多风险…

图片存储问题总结

参考博客&#xff1a; https://blog.csdn.net/BUPT_Kwong/article/details/100972964 今天发现图片保存的一个神奇的问题&#xff0c;就是说原始的jpg图片打开后&#xff0c;重新保存成jpg格式&#xff0c;会发现这个结果不是很对的 example from PIL import Image import n…

房屋出租管理系统小程序需求分析及功能介绍

房屋租赁管理系统适用于写字楼、办公楼、厂区、园区、商城、公寓等商办商业不动产的租赁管理及租赁营销&#xff1b;提供资产管理&#xff0c;合同管理&#xff0c;租赁管理&#xff0c; 物业管理&#xff0c;门禁管理等一体化的运营管理平台&#xff0c;提高项目方管理运营效率…

【qt】QTcpSocket相关的信号

QTcpSocket可以在这里找到相关的信号 进行信号槽的关联 connect():这个信号在connectToHost()被调用并且连接已经成功建立之后发出 disconnected():该信号在套接字断开连接时发出 stateChanged(QAbstractSocket::SocketState socketState):每当QAbstractSocket的状态发生变化…

基于Adaboost的数据分类算法matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.本算法原理 5.完整程序 1.程序功能描述 基于Adaboost的数据分类算法matlab仿真,分别对比线性分类和非线性分类两种方式。 2.测试软件版本以及运行结果展示 MATLAB2022A版本运行 &#xff08;完整程序…

Python - Word转TXT文本,或TXT文本转Word

Word文档&#xff08;.doc或.docx&#xff09;和纯文本文件&#xff08;.txt&#xff09;是两种常用的文件格式。Word文档通常用于复杂的文档处理和排版&#xff0c;而纯文本文件则用于存储和传输纯文本信息。了解如何在这两种格式之间进行转换能提高工作效率&#xff0c;并便于…

Spring Boot中@Async注解的使用及原理 + 常见问题及解决方案

&#x1f604; 19年之后由于某些原因断更了三年&#xff0c;23年重新扬帆起航&#xff0c;推出更多优质博文&#xff0c;希望大家多多支持&#xff5e; &#x1f337; 古之立大事者&#xff0c;不惟有超世之才&#xff0c;亦必有坚忍不拔之志 &#x1f390; 个人CSND主页——Mi…

AV1 编码标准帧间预测技术详细说明

AV1 编码标准帧间预测 AV1&#xff08;AOMedia Video1&#xff09;是一种开源的视频编码格式&#xff0c;它在帧间预测技术上做出了显著的改进和扩展&#xff0c;以提供比现有标准更高的压缩效率和更好的视频质量。以下是AV1帧间预测技术的几个关键点&#xff1a; 参考帧扩展&a…