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

文章目录

    • 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 {@Idprivate 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 {@Autowiredprivate MongoTemplate mongoTemplate;@Testpublic 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 {@Idprivate String id;private Item item;private int qty;private List<Object> tags;@Datapublic 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 {@Idprivate String id;private String item;private int quantity;private Carrier carrier;@Datapublic 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 {@Idprivate 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 {@Idprivate 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.rhkb.cn/news/376331.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

RocketMQ~架构了解

简介 RocketMQ 具有高性能、高可靠、高实时、分布式 的特点。它是一个采用 Java 语言开发的分布式的消息系统&#xff0c;由阿里巴巴团队开发&#xff0c;在 2016 年底贡献给 Apache&#xff0c;成为了 Apache 的一个顶级项目。 在阿里内部&#xff0c;RocketMQ 很好地服务了集…

修复 Ubuntu 24.04 Dock 丢失应用程序图标

找出应用程序窗口的类名 首先&#xff0c;您需要启动应用程序窗口。然后&#xff0c;按 Alt F2 启动“运行 Command”对话框。当对话框打开时&#xff0c;输入 lg 并按 Enter 键。 在该窗口中&#xff0c;单击Windows按钮&#xff0c;然后找出目标应用程序窗口的类名称。 在/…

使用 Apache Pulsar 构建弹性可扩展的事件驱动应用

本视频来自 2024 Apache Pulsar 欧洲峰会&#xff0c;由 David Kjerrumgaard, 《Pulsar in Action》书作者给大家带来的《使用 Apache Pulsar 构建弹性可扩展的事件驱动应用》分享。 嘉宾&#xff5c;David Kjerrumgaard&#xff0c;Apache Pulsar Committer&#xff0c;《Pul…

Android焦点之SurfaceFlinger的apply

接animate()的openSurfaceTransaction(),prepareSurfaces(),closeSurfaceTransaction() 1. mService.openSurfaceTransaction()&#xff0c;通过SurfaceControl来通知native开始一个Transaction&#xff1b; 2. mService.closeSurfaceTransaction()&#xff0c;通过SurfaceCo…

InjectFix 热更新解决方案

简介 今天来谈一谈&#xff0c;项目种的客户端热更新解决方案。InjectFix是腾讯xlua团队出品的一种用于Unity中C#代码热更新热修复的解决方案。支持Unity全系列&#xff0c;全平台。与xlua的思路类似&#xff0c;InjectFix解决的痛点主要在于Unity中C#代码写的逻辑在发包之后无…

主机安全-开源HIDS字节跳动Elkeid安装使用

目录 概述什么是HIDSHIDS与NIDS的区别EDR、XDR是啥&#xff1f; Elkeid架构Elkeid Agent && Agent centerElkeid DriverElkeid RASPElkeid HUBService DiscoveryManager安装数据采集规则&告警 参考 概述 什么是HIDS HIDS&#xff08; host-based intrusion detec…

LeetCode 3011.判断一个数组是否可以变为有序

注&#xff1a;这个题目有序的意思是“升序” 解法一&#xff1a;bubblesort O(nlogn) 核心思想&#xff1a;冒泡每次会将一个数归位到最后的位置上&#xff0c;所以我们如果碰到无法向右交换的数字&#xff0c;即可return false class Solution { public:// 返回一个十进制…

计算机网络——网络层(IP地址与MAC地址、地址解析协议ARP、IP数据报格式以及转发分组、ICMP、IPV6)

IP地址与MAC地址 由于MAC地址已固化在网卡上的ROM 中&#xff0c;因此常常将 MAC地址称为硬件地址或物理地址&#xff1b;物理地址的反义词就是虚拟地址、软件地址或逻辑地址&#xff0c;IP地址就属于这类地址。 从层次的角度看&#xff0c;MAC地址是数据链路层使用的地址&…

如何查找电脑的MAC地址

一. 什么是mac地址&#xff1f; mac地址本质上帮助我们连接到我们遇到的大多数本地网络。每个网络适配器通常由网络接口​​控制器(NIC) 制造商分配一个唯一的 mac 地址。 二. 如何查找mac地址 1.点击网络和Internet设置 2.点击WLAN点击硬件属性 3.即可查看mac地址

Facebook 开源计算机视觉 (CV) 和 增强现实 (AR) 框架 Ocean

Ocean 是一个独立于平台的框架&#xff0c;支持所有主要操作系统&#xff0c;包括 iOS、Android、Quest、macOS、Windows 和 Linux。它旨在彻底改变计算机视觉和混合现实应用程序的开发。 Ocean 主要使用 C 编写&#xff0c;包括计算机视觉、几何、媒体处理、网络和渲染&#x…

安全防御,防火墙配置NAT转换智能选举综合实验

一、实验拓扑图 二、实验需求 1、办公区设备可以通过电信链路和移动链路上网(多对多的NAT&#xff0c;并且需要保留一个公网IP不能用来转换) 2、分公司设备可以通过总公司的移动链路和电信链路访问到Dmz区的http服务器 3、多出口环境基于带宽比例进行选路&#xff0c;但是&…

JavaWeb__正则表达式

目录 1. 正则表达式简介2. 正则表达式体验2.1 验证2.2 匹配2.3 替换2.4 全文查找2.5 忽略大小写2.6 元字符使用2.7 字符集合的使用2.8 常用正则表达式 1. 正则表达式简介 正则表达式是描述字符模式的对象。正则表达式用于对字符串模式匹配及检索替换&#xff0c;是对字符串执行…

JMeter案例分享:通过数据验证的错误,说说CSV数据文件设置中的线程共享模式

前言 用过JMeter参数化的小伙伴&#xff0c;想必对CSV Data Set Config非常熟悉。大家平时更关注变量名称&#xff0c;是否忽略首行等参数&#xff0c;其余的一般都使用默认值。然而我最近遇到一个未按照我的预想读取数据的案例&#xff0c;原因就出在最后一个参数“线程共享模…

IP中转是什么?IP中转会导致网速下降吗

在互联网通信中&#xff0c;IP中转是一个重要的概念&#xff0c;它涉及到数据包的路由和转发。但很多人对于IP中转及其对网络速度的影响并不十分了解。本文将详细解释IP中转的含义&#xff0c;并探讨它是否会导致网速下降。 IP中转是什么&#xff1f; IP中转&#xff0c;也称…

Spring Boot集成easyposter快速入门Demo

1.什么是easyposter&#xff1f; easyposter是一个简单的,便于扩展的绘制海报工具包 使用场景 在日常工作过程中&#xff0c;通常一些C端平台会伴随着海报生成与分享业务。因为随着移动互联网的迅猛发展&#xff0c;社交分享已成为我们日常生活的重要组成部分。海报分享作为…

JavaDS —— 单链表 与 LinkedList

顺序表和链表区别 ArrayList &#xff1a; 底层使用连续的空间&#xff0c;可以随机访问某下标的元素&#xff0c;时间复杂度为O&#xff08;1&#xff09; 但是在插入和删除操作的时候&#xff0c;需要将该位置的后序元素整体往前或者向后移动&#xff0c;时间复杂度为O&…

【银河麒麟服务器操作系统】系统夯死分析及处理建议

了解银河麒麟操作系统更多全新产品&#xff0c;请点击访问麒麟软件产品专区&#xff1a;https://product.kylinos.cn 服务器环境以及配置 【机型】物理机 处理器&#xff1a; Intel 内存&#xff1a; 512G 整机类型/架构&#xff1a; X86_64 【内核版本】 4.19.90-25…

【学习笔记】无人机(UAV)在3GPP系统中的增强支持(五)-同时支持无人机和eMBB用户数据传输的用例

引言 本文是3GPP TR 22.829 V17.1.0技术报告&#xff0c;专注于无人机&#xff08;UAV&#xff09;在3GPP系统中的增强支持。文章提出了多个无人机应用场景&#xff0c;分析了相应的能力要求&#xff0c;并建议了新的服务级别要求和关键性能指标&#xff08;KPIs&#xff09;。…

集成excel工具:自定义导入回调监听器、自定义类型转换器、web中的读

文章目录 I 封装导入导出1.1 定义工具类1.2 自定义读回调监听器: 回调业务层处理导入数据1.3 定义文件导入上下文1.4 定义回调协议II 自定义转换器2.1 自定义枚举转换器2.2 日期转换器2.3 时间、日期、月份之间的互转2.4 LongConverterIII web中的读3.1 使用默认回调监听器3.2…

防御第二次作业完成接口配置实验

一、实验括扑图 二、实验要求 1.防火墙向下使用子接口分别对应生产区和办公区 2.所有分区设备可以ping通网关 三、实验思路 1、配置各设备的IP地址 2、划分VLAN及VLAN的相关配置 3、配置路由及安全策略 四、实验步骤 1、配置PC跟Client还有server配置&#xff0…