near 操作符限制
即使有MongoDB Search索引,也无法使用 near操作符查询存储在大量中的数字或日期值。您只能使用该范围来查询数组内的索引数字或日期值。
定义
语法
near 通过以下语法实现:
{ $search: { "index": <index name>, // optional, defaults to "default" "near": { "path": "<field-to-search>", "origin": <date-or-number>, "pivot": <pivot-distance>, "score": <score-options> } } }
选项
near 使用以下词条来构造查询:
字段 | 类型 | 说明 | 必要性 | |||
|---|---|---|---|---|---|---|
| 日期、数字或地理位置 | 是 | ||||
| 字符串或字符串数组 | 要搜索的一个或多个带索引字段。 | 是 | |||
| 数字 | 用于计算MongoDB搜索结果文档分数的值。分数使用以下公式计算: 其中, 当结果的索引字段值与 如果
| 是 | |||
| 对象 | 分配给匹配搜索结果的分数。您可以使用以下选项修改默认分数:
有关在查询中使用 要了解更多信息,请参阅评分行为。 | no |
评分行为
MongoDB Search score 是MongoDB Search 结果与 origin 的接近程度的度量。score 在 0 和 1 之间调整,其中 1 为精确匹配,0 为远程匹配。当MongoDB搜索结果与 origin 的距离等于使用 pivot 计算的距原点的距离时,分数等于 0.5。
near 操作符使用以下距离衰减函数来计算文档得分:
pivot score = ------------------ pivot + distance
其中每个术语的定义如下:
因子 | 说明 | |
|---|---|---|
| 指定为参考点的值,如果 | |
|
其中:
|
可以在查询中使用 score 选项修改默认分数。要了解有关选项的详细信息,请参阅修改分数。
示例
The number and date examples use the movies collection in the sample_mflix database. The GeoJSON point example uses the listingsAndReviews collection in the sample_airbnb database.
If you load the sample data on your cluster, you can create the static indexes using the index definitions in the examples below or the dynamic index and run the example queries on your cluster.
提示
If you've already loaded the sample dataset, refer to the MongoDB Search Quick Start tutorial to create an index definition and run MongoDB Search queries.
数字示例
以下示例使用 near 操作符查询数字字段。以下查询使用名为 runtimes 的索引,该索引动态地为 movies 集合中的所有字段创建索引。该查询在 movies 集合中搜索 runtime 字段值接近 279 的文档。
基本示例
The following query returns all documents that match the search criteria. It includes a $limit stage to limit the output to 7 results and a $project stage to:
排除
title和runtime之外的所有字段添加字段
score
score 是使用 pivot 计算得出。
1 db.movies.aggregate([ 2 { 3 $search: { 4 "index": "runtimes", 5 "near": { 6 "path": "year", 7 "origin": 2000, 8 "pivot": 2 9 } 10 } 11 }, 12 { 13 $limit: 7 14 }, 15 { 16 $project: { 17 "_id": 0, 18 "title": 1, 19 "runtime": 1, 20 score: { $meta: "searchScore" } 21 } 22 } 23 ])
[ { runtime: 279, title: 'The Kingdom', score: 1 }, { runtime: 279, title: 'The Kingdom', score: 1 }, { runtime: 279, title: 'The Jinx: The Life and Deaths of Robert Durst', score: 1 }, { runtime: 281, title: 'Les Misèrables', score: 0.5 }, { runtime: 277, title: 'Tokyo Trial', score: 0.5 }, { runtime: 283, title: 'Scenes from a Marriage', score: 0.3333333432674408 }, { runtime: 274, title: 'The Crimson Petal and the White', score: 0.2857142984867096 } ]
在MongoDB搜索结果中,电影 The Kingdom 和 The Jinx: The Life and Deaths of Robert Durst 的分数为 1.0,因为它们的 runtime字段值 279 完全匹配。电影 Les Misèrables 和 Tokyo Trial 的分数为 0.5,因为它们的 runtime字段值与 279 相差 2 个单位。
元数据示例
以下查询返回搜索条件的元数据结果。也就是说,它使用 $searchMeta 阶段来获取以下存储桶(年份)中符合搜索条件的电影数量:
2000,包括此存储桶的下限
2005,2000 存储桶的不含上限以及此存储桶的包含下限
2010,2005 存储桶的不含上限以及此存储桶的包含下限
2010,2010 存储桶的独占上限
1 db.movies.aggregate([ 2 { 3 "$searchMeta": { 4 "facet": { 5 "operator": { 6 "near": { 7 "path": "runtime", 8 "origin": 279, 9 "pivot": 2 10 } 11 }, 12 "facets": { 13 "yearFacet": { 14 "type": "number", 15 "path": "year", 16 "boundaries": [2000, 2005, 2010, 2015 ] 17 } 18 } 19 } 20 } 21 } 22 ])
[ { count: { lowerBound: Long('20910') }, facet: { yearFacet: { buckets: [ { _id: 2000, count: Long('3058') }, { _id: 2005, count: Long('4012') }, { _id: 2010, count: Long('4669') } ] } } } ]
日期示例
以下示例使用 near 操作符查询日期字段。
例子
以下名为 releaseddate 的索引定义对 movies 集合中的 released 字段值编制索引:
1 { 2 "mappings": { 3 "dynamic": false, 4 "fields": { 5 "released": { 6 "type": "date" 7 } 8 } 9 } 10 }
The following query searches for movies released near September 13, 1. It includes a $limit stage to limit the output to 3 results and a $project stage to:
排除
title和released之外的所有字段添加字段
score
结果的 score 将使用 pivot 计算得出。
注意
pivot 此处以毫秒为单位,7,776,000,000 ms 等于大约三个月。
1 db.movies.aggregate([ 2 { 3 $search: { 4 "index": "releaseddate", 5 "near": { 6 "path": "released", 7 "origin": ISODate("1915-09-13T00:00:00.000+00:00"), 8 "pivot": 7776000000 9 } 10 } 11 }, 12 { 13 $limit: 3 14 }, 15 { 16 $project: { 17 "_id": 0, 18 "title": 1, 19 "released": 1, 20 score: { $meta: "searchScore" } 21 } 22 } 23 ])
以上查询会返回以下搜索结果:
{ "title" : "Regeneration", "released" : ISODate("1915-09-13T00:00:00Z"), "score" : 1 } { "title" : "The Cheat", "released" : ISODate("1915-12-13T00:00:00Z"), "score" : 0.49723756313323975 } { "title" : "Hell's Hinges", "released" : ISODate("1916-03-05T00:00:00Z"), "score" : 0.34090909361839294 }
在上面的MongoDB Search 结果中,电影 Regeneration 的分数为 1,因为 1915-09-13 的 released字段值是精确匹配项。在 1915-12-13 上映的电影 The Cheat 的分数约为 0.5,因为 1915-09-13 的 released字段值与 origin 的距离约为 7,776,000,000 毫秒。
GeoJSON 点示例
以下示例使用 near 操作符查询 sample_airbnb.listingsAndReviews 集合中的 GeoJSON 点对象。以下索引定义对 listingsAndReviews 集合中的 address.location 和 property_type 字段编制索引。
例子
1 { 2 "mappings": { 3 "fields": { 4 "address": { 5 "fields": { 6 "location": { 7 "type": "geo" 8 } 9 }, 10 "type": "document" 11 }, 12 "property_type": { 13 "type": "string" 14 } 15 } 16 } 17 }
基本示例
以下示例使用 near 操作符查询 sample_airbnb.listingsAndReviews 集合中的 address.location 字段。
例子
The following query searches for properties in Portugal. It includes a $limit stage to limit the output to 3 results and a $project stage to:
排除
name和address之外的所有字段添加字段
score
结果的 score 将使用 pivot 计算得出。请注意,此处测量的 pivot 的单位为米,1000 米等于 1 公里。
1 db.listingsAndReviews.aggregate([ 2 { 3 "$search": { 4 "near": { 5 "origin": { 6 "type": "Point", 7 "coordinates": [-8.61308, 41.1413] 8 }, 9 "pivot": 1000, 10 "path": "address.location" 11 } 12 } 13 }, 14 { 15 $limit: 3 16 }, 17 { 18 $project: { 19 "_id": 0, 20 "name": 1, 21 "address": 1, 22 score: { $meta: "searchScore" } 23 } 24 } 25 ])
以上查询会返回以下搜索结果:
1 { 2 "name" : "Ribeira Charming Duplex", 3 "address" : { 4 "street" : "Porto, Porto, Portugal", 5 "suburb" : "", 6 "government_area" : "Cedofeita, Ildefonso, Sé, Miragaia, Nicolau, Vitória", 7 "market" : "Porto", 8 "country" : "Portugal", 9 "country_code" : "PT", 10 "location" : { 11 "type" : "Point", 12 "coordinates" : [ -8.61308, 41.1413 ], 13 "is_location_exact" : false 14 } 15 }, 16 "score" : 1 17 } 18 { 19 "name" : "DB RIBEIRA - Grey Apartment", 20 "address" : { 21 "street" : "Porto, Porto, Portugal", 22 "suburb" : "", 23 "government_area" : "Cedofeita, Ildefonso, Sé, Miragaia, Nicolau, Vitória", 24 "market" : "Porto", 25 "country" : "Portugal", 26 "country_code" : "PT", 27 "location" : { 28 "type" : "Point", 29 "coordinates" : [ -8.61294, 41.14126 ], 30 "is_location_exact" : true 31 } 32 }, 33 "score" : 0.9876177310943604 34 } 35 { 36 "name" : "Ribeira 24 (4)", 37 "address" : { 38 "street" : "Porto, Porto, Portugal", 39 "suburb" : "", 40 "government_area" : "Cedofeita, Ildefonso, Sé, Miragaia, Nicolau, Vitória", 41 "market" : "Porto", 42 "country" : "Portugal", 43 "country_code" : "PT", 44 "location" : { 45 "type" : "Point", 46 "coordinates" : [ -8.61318, 41.14107 ], 47 "is_location_exact" : false 48 } 49 }, 50 "score" : 0.973789632320404 51 }
结果显示,距离指定坐标较远的属性的得分较低。
复合示例
以下示例使用 compound 操作符查询 sample_airbnb.listingsAndReviews 集合中的 property_type 和 address.location 字段。
例子
The following query searches for apartments in Hong Kong near a specified GeoJSON point. The query uses must to specify the search condition, which must be met, and should to specify preference for location. It includes a $limit stage to limit the output to 3 results and a $project stage to:
排除
property_type和address之外的所有字段添加字段
score
score 是使用 pivot 字段计算得出。请注意,此处测量的 pivot 的单位为米,1000 米等于 1 公里。
1 db.listingsAndReviews.aggregate([ 2 { 3 $search: { 4 "compound": { 5 "must": { 6 "text": { 7 "query": "Apartment", 8 "path": "property_type" 9 } 10 }, 11 "should": { 12 "near": { 13 "origin": { 14 "type": "Point", 15 "coordinates": [114.15027, 22.28158] 16 }, 17 "pivot": 1000, 18 "path": "address.location" 19 } 20 } 21 } 22 } 23 }, 24 { 25 $limit: 3 26 }, 27 { 28 $project: { 29 "_id": 0, 30 "property_type": 1, 31 "address": 1, 32 score: { $meta: "searchScore" } 33 } 34 } 35 ])
以上查询会返回以下搜索结果:
1 { 2 "property_type" : "Apartment", 3 "address" : { 4 "street" : "Hong Kong, Hong Kong Island, Hong Kong", 5 "suburb" : "Central & Western District", 6 "government_area" : "Central & Western", 7 "market" : "Hong Kong", 8 "country" : "Hong Kong", 9 "country_code" : "HK", 10 "location" : { 11 "type" : "Point", 12 "coordinates" : [ 114.15027, 22.28158 ], 13 "is_location_exact" : true 14 } 15 }, 16 "score" : 1.177286982536316 17 } 18 { 19 "property_type" : "Apartment", 20 "address" : { 21 "street" : "Hong Kong, Hong Kong Island, Hong Kong", 22 "suburb" : "Central & Western District", 23 "government_area" : "Central & Western", 24 "market" : "Hong Kong", 25 "country" : "Hong Kong", 26 "country_code" : "HK", 27 "location" : { 28 "type" : "Point", 29 "coordinates" : [ 114.15082, 22.28161 ], 30 "is_location_exact" : true 31 } 32 }, 33 "score" : 1.1236450672149658 34 } 35 { 36 "property_type" : "Apartment", 37 "address" : { 38 "street" : "Hong Kong, 39 Hong Kong Island, Hong Kong", 40 "suburb" : "Mid-Levels", 41 "government_area" : "Central & Western", 42 "market" : "Hong Kong", 43 "country" : "Hong Kong", 44 "country_code" : "HK", 45 "location" : { 46 "type" : "Point", 47 "coordinates" : [ 114.15007, 22.28215 ], 48 "is_location_exact" : true 49 } 50 }, 51 "score" : 1.114811897277832 52 }